Timer0 as counter with Microchip PIC10F202 - counter

I developing RC switch for my RC glider.
I have microkontroller Microchip PIC10F202 and I have problem with ON/OFF LED Lights.
I want triggering input PPM signal from RC receiver, I setted GP2 as input (by T0CKI and count for every rise edge - from low to high), but LED is still ON, not reacting on input signal from RC receiver.
I post my source code in C language, I can not ASM language.
// this is header file with some macros and function prototypes
#ifndef XC_HEADER_TEMPLATE_H
#define XC_HEADER_TEMPLATE_H
#include <xc.h>
#define _XTAL_FREQ 4000000
#define KONST_ON 50
#define KONST_OFF 1000
#define STROBO_LED GP0
#define NAVI_LED GP1
#define RC_SIGNAL GP2
#define STAV_ON 1
#define STAV_OFF 0
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
void setup ();
void flashing ();
#endif
// In this function is setup for microkontroller
#include <xc.h>
#include "prototypy.h"
void setup ()
{
OSCCAL = 0b0111111;
//STATUS = 0b00111000;
OPTION = 0b11100111;
TRISGPIO = 0b0000;
};
// This is function for LED flashing
#include <xc.h>
#include "prototypy.h"
void flashing ()
{
__delay_ms (KONST_OFF);
STROBO_LED = STAV_OFF;
__delay_ms (KONST_ON);
STROBO_LED = STAV_ON;
};
// in this main function I do logical product, where I have logical state from pin GP2 and number 1
#include <xc.h>
#include "prototypy.h"
// Code protection bit
#pragma config CP = OFF
// Watchdog timer
#pragma config WDTE = OFF
// Pin function
#pragma config MCLRE = OFF
void main ()
{
setup ();
while (1)
{
if (RC_SIGNAL & 1)
{
flashing ();
}
}
}
Please, can me someone help and found error in my source code?

I'am not really familar with that devive, but I guess you Pin RC_SIGNAL is not configured as an Input. Please try
TRISGPIO = 0b0100;

Related

The sample code does not work on STM32F103C6

experts.
I am new to STM32.
So I downloaded some sample code from github.
https://github.com/yohanes-erwin/stm32f103-keil
And I download the simple led blinking code of it to the STM32F103C6 developing board but it doesn't work at all.
The original program embedded on the chip had been erased successfully ( originally the led was always on and LCD screen shows some text, but now after I download the code, the led is off and screen off. So I think the downloading is successful.) but the code does not work.
When I download the original code to the chip, it works again. So I think the chip isn't broken.
I think it's because of compatibility of sample code and my chip. The sample code was written for STM32F103C8. But it was a very simple code. What is the reason?
Here is the code.
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
void delay(unsigned int nCount);
GPIO_InitTypeDef GPIO_InitStruct;
int main (void)
{
// Enable clock for GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// Configure PA4 as push-pull output
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
while (1)
{
/* Toggle LED on PA0 */
// Reset bit will turn on LED (because the logic is interved)
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
delay(1000);
// Set bit will turn off LED (because the logic is interved)
GPIO_SetBits(GPIOA, GPIO_Pin_4);
delay(1000);
}
}
// Delay function
void delay(unsigned int nCount)
{
unsigned int i, j;
for (i = 0; i < nCount; i++)
for (j = 0; j < 0x2AFF; j++);
}

Simulink S-Function Builder with External Library and Runtime Binary

I am trying to make a S-Function (written in C and using SDL library) in Simulink to read joystick values from the device and output them to Simulink. I used before the standard aerospace library joystick block, however, this does not support compiling (which is needed for Rapid Acceleration). Hence, I decided to write my own S-Function.
I managed to make a simple C program that uses SDL (I downloaded https://www.libsdl.org/download-2.0.php) to read values of joystick and print to terminal:
#include <stdio.h>
#include <unistd.h>
#include "SDL2/SDL.h"
static SDL_Joystick *joy = NULL;
int
main(int argc, char *argv[])
{
// ITIALIZE:
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if (SDL_NumJoysticks() > 0) {
// Open joystick
joy = SDL_JoystickOpen(0);
if (joy) {
printf("Opened Joystick 0\n");
printf("Name: %s\n", SDL_JoystickNameForIndex(0));
printf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
printf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
} else {
printf("Could not open Joystick 0\n");
return 0;
}
}
SDL_JoystickEventState(SDL_IGNORE);
// READ VALUES:
for (int i = 1; i < 100; ++i){
SDL_JoystickUpdate();
for (int j = 0; j < SDL_JoystickNumAxes(joy); ++j) {
int value = (((int) SDL_JoystickGetAxis(joy, j)) + 32768);
printf("Axes %d: %d ", j, value);
}
printf("\n");
usleep(100000);
}
// CLOSE:
if (SDL_JoystickGetAttached(joy)) {
SDL_JoystickClose(joy);
}
return 1;
}
I compile the C code in Code::Blocks with linkers:
-lmingw32 -lSDL2main -lSDL2
The compiled .exe requires runtime binary SDL.dll, which is simply located in the same folder as the compilation, and everything works.
The problem is, how to transfer the above to work in Simulink environment? I have transferred the code into Simulink S-Function builder:
/* Includes_BEGIN */
#include "SDL2/SDL.h"
#include <stdio.h>
/* Includes_END */
/* Externs_BEGIN */
static SDL_Joystick *joy = NULL;
/* Externs_END */
void sunf_joystick_Start_wrapper(void)
{
/* Start_BEGIN */
// ITIALIZE:
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if (SDL_NumJoysticks() > 0) {
// Open joystick
joy = SDL_JoystickOpen(0);
if (joy) {
ssPrintf("Opened Joystick 0\n");
ssPrintf("Name: %s\n", SDL_JoystickNameForIndex(0));
ssPrintf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
ssPrintf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
ssPrintf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
} else {
ssWarning("Warning:Joystick","Could not open Joystick 0\n");
}
}
SDL_JoystickEventState(SDL_IGNORE);
/* Start_END */
}
void sunf_joystick_Outputs_wrapper(real_T *y0)
{
/* Output_BEGIN */
SDL_JoystickUpdate();
for (int j = 0; j < SDL_JoystickNumAxes(joy); ++j) {
y0[j] = (((int) SDL_JoystickGetAxis(joy, j)) + 32768);
}
/* Output_END */
}
void sunf_joystick_Terminate_wrapper(void)
{
/* Terminate_BEGIN */
if (SDL_JoystickGetAttached(joy)) {
SDL_JoystickClose(joy);
}
/* Terminate_END */
}
and added the LIB_PATH and INCL_PATH to point for the SDL library:
S-function builder Libraries tab
However, I get a lot of similar error messages when trying to build through the GUI:
C:\Users\user\AppData\Local\Temp\mex_121831936796334_22096\sunf_joystick_wrapper.obj:sunf_joystick_wrapper.c:(.text+0xe): undefined reference to `SDL_InitSubSystem'
To me it seems that the libraries are not linked correctly. An idea how to fix this? I have tried to build it also with mex through MATLAB command line, not successful, and feels also wrong way to do it.
Also, any advice where the the runtime library SDL.dll should be stored or referenced if the compilation is successful?
All files in: https://github.com/JohannesSoikkeli/Simulink_joystick
Many thanks!

Why can I not print non-ASCII characters to the console in curses mode?

Please consider this simple snippet:
#include <stdio.h>
#include <curses.h>
#include <stdlib.h>
#include <stdbool.h>
#include <signal.h>
void cleanup(int signal)
{
endwin();
exit(0);
}
int main()
{
initscr();
struct sigaction cleanup_action = { .sa_handler = cleanup, .sa_flags = 0 };
sigfillset(&cleanup_action.sa_mask);
sigaction(SIGINT, &cleanup_action, NULL);
cbreak();
keypad(stdscr, TRUE);
noecho();
mvaddstr(2, 2, "🧱");
mvaddstr(2, 3, "🧱");
mvaddstr(2, 4, "🧱");
mvaddstr(3, 2, "⬜");
mvaddstr(3, 2, "âš¾");
mvaddstr(3, 4, "⬜");
refresh();
while(true) getch();
return 0;
}
(No, I'm not certain that my clean-up on exit is correct, but that's not the point.)
Why are the emojis not being printed out?
When I run this program this is what I see:
���~_��
�~��~\
I don't understand this because according to POSIX specification:
addnstr, addstr, mvaddnstr, mvaddstr, mvwaddnstr, mvwaddstr waddnstr, waddstr - add a string of multi-byte characters without rendition to a window and advance cursor
"MULTI-BYTE" they say! So I guess this should print out correctly! I'm not limited to ASCII!
Also, I guess my terminal can handle these characters. This is because as opposed to curses.h, stdio.h is able to print them correctly:
#include <stdio.h>
int main()
{
printf("🧱⬜⚾\n");
return 0;
}
This prints out:
🧱⬜⚾
How can I print emojis with curses.h?

ADC on STM32L100C

I've been reading a lot online to figure what is not working in my code, but it seems like the ADC conversion in my code never starts... Not matter what I do, the EOC Flag always remain to 0 and I am currently out of ideas. Making the ADC work should be simple, but for some reason, I am completly unable to make it work.
I'd be very grateful if someone could show me where my mistakes seems to be. I am using the STM32L100CR-Discovery.
/* Standard includes. */
#include "stm32l1xx.h"
#include "stm32l1xx_rcc.h"
#include "stm32l1xx_gpio.h"
#include "stm32l1xx_exti.h"
#include "stm32l1xx_syscfg.h"
#include "stm32l1xx_spi.h"
#include "stm32l1xx_adc.h"
#include "stdio.h"
#include "misc.h"
void ADC_Initialization (void)
{
ADC_DeInit( ADC1);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStruct.ADC_NbrOfConversion = 1;
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_CommonInitTypeDef ADC_CommonInitStruct;
ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div1;
ADC_CommonInit(&ADC_CommonInitStruct);
ADC_Cmd(ADC1, ENABLE);
ADC_BankSelection(ADC1, ADC_Bank_A);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_4Cycles);
ADC_TempSensorVrefintCmd (ENABLE);
}
int Read_ADC(void)
{
ADC_SoftwareStartConv(ADC1);
int statut = ADC_GetSoftwareStartConvStatus(ADC1);
printf("%d", statut);
ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
int valeur = ADC_GetConversionValue(ADC1);
return valeur;
}
int main(void)
{
ADC_Initialization();
int ADC_Valeur = 0;
while(1)
{
ADC_Valeur = Read_ADC();
printf("%d", ADC_Valeur);
}
}
Thanks in advance!
In the end, I did manage to find my problem! If anyone ever happens to search for the solution here it is: First, I did mess up this line :
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE);
It should read :
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
But it is also necessary on the STM32L100C to activate the HSI oscillator clock, which is not done in the library. Adding this line somewhere in the initialization should work:
RCC -> CR |= (0x1U << (0U));

how to make constant variables being used in s-functions as tunable in matlab

i have written a simple s-function which calls a function inside a c code which models the single track model. i am using constant variables for storing mass,yaw moment of inertia,steering ratio etc. I wanted to know how to make these variables tunable. i want to create a subsystem out of my s-function and then use realtime workshop->generate s-function and select the tunable parameters from the list. but for now am not able to find any tunable parameters since i have not specified anything as tunable
this is my s-function code
#define S_FUNCTION_NAME single_track
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include "single_track_func.c"
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
initialization();
}
#endif
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return; /* Parameter mismatch will be reported by Simulink */
}
if (!ssSetNumInputPorts(S, 2)) return;
ssSetInputPortWidth(S, 0, 1);
ssSetInputPortDirectFeedThrough(S, 0, 1);
ssSetInputPortWidth(S, 1, 1);
ssSetInputPortDirectFeedThrough(S, 1, 1);
if (!ssSetNumOutputPorts(S,3)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetOutputPortWidth(S, 1, 1);
ssSetOutputPortWidth(S, 2, 1);
ssSetNumSampleTimes(S, 1);
ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
ssSetOptions(S,
SS_OPTION_WORKS_WITH_CODE_REUSE |
SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_USE_TLC_WITH_ACCELERATOR);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
retvale obj_b;
InputRealPtrsType v_1 = ssGetInputPortRealSignalPtrs(S,0); //velocity
InputRealPtrsType delta_1 = ssGetInputPortRealSignalPtrs(S,1); //steering angle
real_T *a_y_1 = ssGetOutputPortRealSignal(S,0); //lateral acceleration
real_T *psi_dot_1 = ssGetOutputPortRealSignal(S,1); //yaw velocity
real_T *beta_1 = ssGetOutputPortRealSignal(S,2); //attitude angle
obj_b=singletrack((double)*(*v_1),(double)*(*delta_1));
*a_y_1 = obj_b.a_y; //lateral acceleration
*psi_dot_1 =obj_b.psi_dot; //yaw velocity
*beta_1 =obj_b.beta;
}
static void mdlTerminate(SimStruct *S)
{
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
and this is the logic file which has the function singletrack()
#include "single_track_func.h"
float a_1_1,a_1_2,a_2_1,a_2_2,b_1_1,b_2_1,psi_dot_prev,beta_prev;
int count;
const int cv=75000; //cornering stiffness front
const int ch=150000; //cornering stiffness rear axle
const int m=1550; //mass of the vehicle kg
const int lv=1.344; //distance from center of gravity to front wheel
const int lh=1.456; //distance from center of gravity to rear wheel
const int theta=2800; //yaw moment of inertia
const int I_s=16; //overall steering ratio
const float dt=0.001;
retvale singletrack(double a,double b)
{
retvale my_obj;
static float beta_dot=0;
static float psi_double_dot=0;
static float beta_previous=0;
static float psi_dot_previous=0;
beta_previous = beta_prev;
psi_dot_previous = psi_dot_prev;
a_1_1 = ((-cv-ch)/((m)*(a)));
a_1_2 = ((m*(a)*(a))-((ch*lh)-(cv*lv)))/(m*(a)*(a));
a_2_1 = (-(ch*lh)+(cv*lv))/theta;
a_2_2 = ((-ch*lh*lh)-(cv*lv*lv))/(theta*(a));
b_1_1 = -cv/(m*(a));
b_2_1 = (cv*lv)/(theta);
beta_dot = a_1_1 * beta_previous + a_1_2 * psi_dot_previous - b_1_1*((b)/I_s);
psi_double_dot = a_2_1 * beta_previous + a_2_2 * psi_dot_previous + b_2_1*((b)/I_s);
my_obj.beta = beta_dot * dt + beta_previous;
my_obj.psi_dot = psi_double_dot * dt + psi_dot_previous;
my_obj.a_y = (a*((my_obj.psi_dot)-(beta_dot)));
beta_prev=my_obj.beta;
psi_dot_prev=my_obj.psi_dot;
return my_obj;
}
void initialization()
{
psi_dot_prev=0;
beta_prev=0;
}
and the corresponding .h file
#ifndef _SINGLE_TRACK_FUNC_
#define _SINGLE_TRACK_FUNC_
typedef struct retvale
{
double a_y;
double psi_dot;
double beta;
} retvale;
extern struct retvale singletrack(double a,double b);
extern void initialization();
#endif
I know i have to use ssSetSFcnParamTunable() but even after looking at examples have no idea how to do it!!
update:
i declared the variables as global real_T
real_T *m_s,*cv_s,*ch_s,*lv_s,*lh_s,*theta_s,*I_s_s,*dt_s;
and added these lines of codes in my mdlInitializeSizes(). i mex it and everything is fine. but when i use the s-function block and just change the name of the s-function to the mex file the matlab crashes. also i pass these arguments as pointers to my single_track () function
ssSetNumSFcnParams(S, 8);
m_s=mxGetPr(ssGetSFcnParam(S,0));
cv_s=mxGetPr(ssGetSFcnParam(S,1));
ch_s=mxGetPr(ssGetSFcnParam(S,2));
lv_s=mxGetPr(ssGetSFcnParam(S,3));
lh_s=mxGetPr(ssGetSFcnParam(S,4));
theta_s=mxGetPr(ssGetSFcnParam(S,5));
I_s_s=mxGetPr(ssGetSFcnParam(S,6));
dt_s=mxGetPr(ssGetSFcnParam(S,7));
ssSetSFcnParamTunable(S,0,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,1,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,2,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,3,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,4,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,5,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,6,SS_PRM_SIM_ONLY_TUNABLE);
ssSetSFcnParamTunable(S,7,SS_PRM_SIM_ONLY_TUNABLE);
any idea why there is a crash?
For a parameter to be tunable it must be passed as an input from Simulink to your S-Function.
This is done by specifying them in the Parameters part of the S-Function block's dialog (as a comma separated list), and using the ssSetNumSFcnParams method within the S-Function itself to tell the S-function how many parameters to expect (you currently have that set to 0).
Also, within the S-Function you'll need to
Use the ssGetSFcnParam method to get the data (from the dialog into the code).
Use the ssSetSFcnParamTunable method to say that the parameter(s) is tunable.
Then you'll need to rewrite your singletrack function so that all of the parameters are passed into it as inputs rather than being hard coded into the file.
However, looking at the code you've given, it would be far easier to do this all as a MATLAB Function than it would as an S-Function.