静态变量static两种使用方式 一.定义局部变量 2.这样声明的变量,其存储在程序的bss段,而在bss段在程序中执行时会初始化为0. 二.定义全局变量 外部变量extern 作用:声明外部变量,扩展它在程序文件中的作用域。即在文件1定义的全局变量int A,可以在文件2中定义 extern A ,便可调用这个文件1中的全局变量。比如在实际具体工程项目中,在定时器文件中定义的全局变量时间int32_t g_iRunTime ,最长可以表示 24.85天,也就是你的终端可持续运行的时间,在其他项目其他文件中,像主函数文件中也需调用用于判断运行时间则就用extern g_iRunTime调用。 一. 只需返回一个值得时候 二. 要求返回多个值得时候 需要注意的是,一般原则:在程序设计中,再划分模块时要求模块”内聚性”强,与其他模块的“耦合性”弱。简单理解就是,在封装的各个函数中各有自己独立功能,即功能单一,方便调用,而不能搞的太乱。对于全局变量需限制使用。 在项目工程当中,或者简单的C语言代码当中,循环使用的非常普遍,掌握循环的各个形式非常重要,这里简单的介绍下循环控制中continue 与 break的区别。 如上面清晰易懂,在写代码当中或者看懂下载得源代码中,如果不是在主函数main中出现的while(1),其他函数中出现while(1),都必然存在一个break语句,在首先学习看懂源代码的任务中,这点比较重要。(看来这点只适合初学者啊,只要有点经验都知道这些浅显的但关键的知识点) 核心思想:通过消息队列机制,在MAIN函数中,通过消息传递任务来执行。 当某一任务需要执行的时候,通知消息队列,主程序去执行。 主程序在函数中解析消息队列,看有无任务。 **至此,**在主函数mian中的while(1)中调用5,6两个函数询检即可。 队列FIFO运用主要是对CPU分配管理:一般的计算机系统只有一个CPU,如果在系统中的多个进程都满足运行条件,这就可以用一个就绪队列来进行管理。当某个进程需要执行的时候,它的进程名就插入到就绪队列的尾端。如果此队列是空的,CPU就立即执行此进程;如果此队列非空,则该进程就需要排在队列的尾端进行等待。CPU总是首先执行排在队首的进程,一个进程分配的一段时间执行完了,又将它插入队尾进行等待,CPU转而为下一个出现在队首的进程服务。如此。按照“FIFO”的原则一直进行下去,直到执行完的进程从队列中删掉。 队列fifo还可用于许多场景,比如串口fifo,多串口运行时的分配。 这部分我主要是针对stm32的程序来使用的,首先配置systick定时器作为系统滴答定时器。缺省定时周期为1ms。实现了多个软件定时器供主程序使用(精度1ms), 可以通过修改 TMR_COUNT 增减软件定时器个数。 这部分还是主要为CPU处理队列信息的使用做服务的。为每个单一任务设置定时器,一旦到了设定的时间就像队列写入一个该任务消息,直到CPU处理为止,定时器主要实现任务调度的问题。当然,风格不同的工程师有着不同的用法! 配置systick定时器,周期为1ms 软件定时器的设置
C语言总结(stm32嵌入式开发)
文章目录
c程序小知识点总结
1.静态变量static与外部变量extern的使用
// 求阶乘 n! int fac(int) { static int f = 1 ; f = f * n ; return f ; } main() { int i ,n ; float sum; scanf("%d",&n) ; for(i = 1 ;i <= n ;i++) { sum = fac(i) ; } printf("输出%d!= %f ",n,sum) ; }
// eg: static int b[5] ; //则b[0] = 0 ,b[1] = 0等等. 而如果不是这样定义则输出可能是乱码
当定义全局变量只限于本文件使用,而不被其他文件使用,这时可以在定义外部变量的时候加一个static声明。注意定义加了static和不加的外部变量都是存放在静态存储区,而区别就在于上一句的“只限于本文件使用”。2.函数封装后返回值的方法
比如 int fun();函数返回就是int类型的数值。
// 函数fun返回了三个值,通过return1个,和数组s[2]两个,以达到要求 int fun(int str[2]); main() { int s[2] ;//定义一个数组来存放fun函数的返回的a b 之间最大值,最小值 scantf("%d%d",&a,&b); if(fun(a,b,s)) { printf("大的%d,小的%d",a[0],a[1]); } else printf("相等"); } int fun(int a ,int b ,int str[2]) { if(a > b) { str[0] = a ; str[1] = b ; return 1 ; } if(a < b) { str[0] = b ; str[1] = a ; return 1 ; } else return 0 ; }
3.循环控制continue与break的区别
利用代码体现://简介循环控制continue与break的区别 main() { while(表达式一) { if(表达式二) { break ; //跳出循环,也即跳出while语句转执行下面的语句 } } while(表达式一) { if(表达式二) { continue ; //跳到条件限制,也即跳到while语句判断中 } } }
项目程序规范
1.消息队列FIFO
typedef struct { uint8_t *MsgRam; /*队列缓存*/ uint8_t MsgSize; /*队列大小*/ uint8_t MsgCount; /*收到的新消息个数*/ uint8_t MsgWritePoint; /*写指针*/ uint8_t MsgReadPoint; /*读指针*/ }Msg_Fifo; #define TaskSize (100) /*消息队列尺寸*/
typedef enum { Idletask = 0 ; .... //消息类型,根据项目中的各个需要Cpu处理的模块决定 }
void bsp_Init_Msg_Fifo(void) { _MsgTask.MsgSize = TaskSize; _MsgTask.MsgRam = _MsgRam; /*队列缓存*/ _MsgTask.MsgCount = 0; /*新数据个数*/ _MsgTask.MsgReadPoint = 0; /*读指针*/ _MsgTask.MsgWritePoint = 0; /*写指针*/ }
2.软件定时器的使用
方法:在core_cm3.h有一个这样的函数uint32_t SysTick_Config(uint32_t ticks),该函数的形参表示内核时钟多少个周期后触发一次Systick定时中断
– SystemCoreClock / 1000 表示定时频率为 1000Hz, 也就是定时周期为 1ms
– SystemCoreClock / 500 表示定时频率为 500Hz, 也就是定时周期为 2ms
– SystemCoreClock / 2000 表示定时频率为 2000Hz, 也就是定时周期为 500us
所以我们一般在定时器初始化函数中调用SysTick_Config(SystemCoreClock / 1000);形成周期性中断函数每一ms执行中断一次,即需要中断就要写了个中断服务程序void SysTick_Handler(void);该函数主要为下面制定软件定时器的计数每隔1ms进行减一操作。
1.定义定时器结构体以及定时器的个数和各个任务定时器的名称 typedef struct { volatile uint8_t Flag; /* 定时到达标志 */ volatile uint32_t Count; /* 计数器 */ volatile uint32_t PreLoad; /* 计数器预装值 */ }SOFT_TMR; /* 软件定时器个数 */ #define TMR_COUNT 5 //自己设定需要多少软件定时器 /*定义定时器名称*/ #define C_TMR_ID (4) #define C_TMR_ID (3) #define E1_TMR_ID (2) #define E_TMR_ID (1) #define cTMR_ID (0)
总结:本文主要是根据自己的学习稍作总结,本人为新手,非常乐意学习成果,该文在为自己总结并记录的同时希望能帮助到读者!
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算