范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

STM32模拟串口(UART)使用!

  1、添加头文件
  首先我们先添加相应的头文件。既然我们要进行对串口的模拟,因此我们要先了解uart相关的通信协议。由于UART的通信方式是由1个起始位,8个数据位,包含一个奇偶校验位,和结束位构成因此我们将使用单片机中的两个普通的IO口电平的高低进行对相应时序的模拟。
  #include "stm32f10x.h" #include "vuart2.h"2、宏定义
  使用到的io口为  #define OI2_TXD PDout(6) #define OI2_RXD PDin(7)  #define BuadRate2_9600 104  #define Recive2_Byte 19 //接收缓冲器的个数 u8 len2 = 0; //接收计数 u8 USART2_buf[Recive2_Byte];  //接收缓冲区
  将IO口相应的位带操作函数进行宏定义从而使得在对不同的电平的进行转换的时候更为方便,并且减少了调用其他函数的过程所消耗的时间,程序执行效率更高。
  在本次的传输过程中我选用的是使用波特率速率为9600,也就是1s中发送9600个字节,因此对每个字节数据进行计算1000000us/9600可以得出,发一个字节的数据需要进行大概需要 104.16us并且对于相应的电平持续时间要求误差不能超过±5%因此对我们进行时间的控制要求就显得比较重要了。  3、枚举出各个位enum{     COM_START_BIT,     COM_D0_BIT,     COM_D1_BIT,     COM_D2_BIT,     COM_D3_BIT,     COM_D4_BIT,     COM_D5_BIT,     COM_D6_BIT,     COM_D7_BIT,     COM_STOP_BIT, };  u8 recvStat2 = COM_STOP_BIT; u8 recvData2 = 0;4、IO——TXD进行模拟void IO2_TXD(u8 Data) {     u8 i = 0;     OI2_TXD = 0;       delay_us(BuadRate2_9600);     for(i = 0; i < 8; i++)     {         if(Data&0x01)             OI2_TXD = 1;           else             OI2_TXD = 0;                    delay_us(BuadRate2_9600);         Data = Data>>1;     }     OI2_TXD = 1;     delay_us(BuadRate2_9600); }
  由于发送的信号是将TXD信号进行拉低处理,因此在拉低TXD相应的IO口之后进行延时处理,再进行循环对我们需要发送的各个位的数据继续进行发送循环发送完成之后将电平拉高代表停止位。  5、构建发送函数void USART2_Send(u8 *buf, u8 len2) {     u8 t;     for(t = 0; t < len2; t++)     {         IO2_TXD(buf[t]);     } }
  其中的*buf为需要发送的数据,len2为数据长度,进行循环调用IO_TXD进行一个字节一个字节的数据发送。  6、IO口初始化void IO2Config(void)  {     GPIO_InitTypeDef  GPIO_InitStructure;//初始化gpio     NVIC_InitTypeDef NVIC_InitStructure;//中断初始化函数      EXTI_InitTypeDef EXTI_InitStruct;     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);  //使能PD,PC端口时钟             //SoftWare Serial TXD     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;       //选择io口6     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO口速度为50MHz       GPIO_Init(GPIOD, &GPIO_InitStructure);            GPIO_SetBits(GPIOD,GPIO_Pin_6);       //TXD默认电平拉高           //SoftWare Serial RXD     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       GPIO_Init(GPIOD, &GPIO_InitStructure);        GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource7);  //对D7的下降沿进行中断采样,当接收到下降沿时代表接收到数据触发中断处理函数     EXTI_InitStruct.EXTI_Line = EXTI_Line7;//用到了中断7     EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发中断     EXTI_InitStruct.EXTI_LineCmd=ENABLE;     EXTI_Init(&EXTI_InitStruct);//初始化中断       NVIC_InitStructure.NVIC_IRQChannel= EXTI9_5_IRQn ; //中断发生于9-5的中断之中     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;      NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;       NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;       NVIC_Init(&NVIC_InitStructure);   }7、定时器初始化void TIM5_Int_Init(u16 arr,u16 psc) {     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     NVIC_InitTypeDef NVIC_InitStructure;     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能          //定时器TIM5初始化     TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值     TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式     TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位     TIM_ClearITPendingBit(TIM5, TIM_FLAG_Update);     TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM5中断,允许更新中断      //中断优先级NVIC设置     NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM5中断     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能     NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器     }
  对TIM5进行初始化操作使得定时器可以检测到各个位的电平持续性时间从而对接收到的数据进行分析。计时结束后进入中断TIM5处理。  8、外部中断处理函数void EXTI9_5_IRQHandler(void) {     if(EXTI_GetFlagStatus(EXTI_Line7) != RESET)//对中断标志位进行采集     {         if(OI2_RXD == 0)          {             if(recvStat2 == COM_STOP_BIT)             {                 recvStat2 = COM_START_BIT;//将当前的状态设置为开始位                 TIM_Cmd(TIM5, ENABLE);//开启定时器计数             }         }         EXTI_ClearITPendingBit(EXTI_Line7); //清除中断标志     } }9、定时器中断处理函数void TIM5_IRQHandler(void) {       if(TIM_GetFlagStatus(TIM5, TIM_FLAG_Update) != RESET)     {         TIM_ClearITPendingBit(TIM5, TIM_FLAG_Update); //清除中断标志位         recvStat2++; //将位置移动到第一位的数据         if(recvStat2 == COM_STOP_BIT)//当运行到停止位时进入         {             TIM_Cmd(TIM5, DISABLE);//停止tim5             USART2_buf[len2++] = recvData2;//将采集到的各个数据传递给USART2_buf             if(len2 > Recive2_Byte-1)//将数据通过回显到串口调试助手中             {                 len2 = 0;                 USART2_Send(USART2_buf,Recive2_Byte);             }             return;         }         if(OI2_RXD)//采集RXD各个电平         {             recvData2 |= (1 << (recvStat2 - 1));         }else{             recvData2 &= ~(1 << (recvStat2 - 1));         }    }   }整体代码vuart2.c#include "stm32f10x.h" #include "vuart2.h" /** *软件串口的实现(IO模拟串口) * 波特率:9600    1-8-N * TXD : PD6 * RXD : PD7 * 使用外部中断对RXD的下降沿进行触发,使用定时器5按照9600波特率进行定时数据接收。 * Demo功能: 接收11个数据,然后把接收到的数据发送出去 */   #define OI2_TXD PDout(6) #define OI2_RXD PDin(7)  #define BuadRate2_9600 104  #define Recive2_Byte 19 //接收缓冲器的个数 u8 len2 = 0; //接收计数 u8 USART2_buf[Recive2_Byte];  //接收缓冲区  enum{     COM_START_BIT,     COM_D0_BIT,     COM_D1_BIT,     COM_D2_BIT,     COM_D3_BIT,     COM_D4_BIT,     COM_D5_BIT,     COM_D6_BIT,     COM_D7_BIT,     COM_STOP_BIT, };  u8 recvStat2 = COM_STOP_BIT; u8 recvData2 = 0;  void IO2_TXD(u8 Data) {     u8 i = 0;     OI2_TXD = 0;       delay_us(BuadRate2_9600);     for(i = 0; i < 8; i++)     {         if(Data&0x01)             OI2_TXD = 1;           else             OI2_TXD = 0;                    delay_us(BuadRate2_9600);         Data = Data>>1;     }     OI2_TXD = 1;     delay_us(BuadRate2_9600); }      void USART2_Send(u8 *buf, u8 len2) {     u8 t;     for(t = 0; t < len2; t++)     {         IO2_TXD(buf[t]);     } }       void IO2Config(void)  {     GPIO_InitTypeDef  GPIO_InitStructure;     NVIC_InitTypeDef NVIC_InitStructure;      EXTI_InitTypeDef EXTI_InitStruct;     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);  //使能PB,PC端口时钟             //SoftWare Serial TXD     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO口速度为50MHz       GPIO_Init(GPIOD, &GPIO_InitStructure);            GPIO_SetBits(GPIOD,GPIO_Pin_6);                  //SoftWare Serial RXD     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       GPIO_Init(GPIOD, &GPIO_InitStructure);        GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource7);     EXTI_InitStruct.EXTI_Line = EXTI_Line7;     EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发中断     EXTI_InitStruct.EXTI_LineCmd=ENABLE;     EXTI_Init(&EXTI_InitStruct);       NVIC_InitStructure.NVIC_IRQChannel= EXTI9_5_IRQn ;      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;      NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;       NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;       NVIC_Init(&NVIC_InitStructure);   }   void TIM5_Int_Init(u16 arr,u16 psc) {     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     NVIC_InitTypeDef NVIC_InitStructure;     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能          //定时器TIM5初始化     TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值     TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式     TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位     TIM_ClearITPendingBit(TIM5, TIM_FLAG_Update);     TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM5中断,允许更新中断      //中断优先级NVIC设置     NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM4中断     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能     NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器     } void EXTI9_5_IRQHandler(void) {     if(EXTI_GetFlagStatus(EXTI_Line7) != RESET)     {         if(OI2_RXD == 0)          {             if(recvStat2 == COM_STOP_BIT)             {                 recvStat2 = COM_START_BIT;                 TIM_Cmd(TIM5, ENABLE);             }         }         EXTI_ClearITPendingBit(EXTI_Line7);     } }  void TIM5_IRQHandler(void) {       if(TIM_GetFlagStatus(TIM5, TIM_FLAG_Update) != RESET)     {         TIM_ClearITPendingBit(TIM5, TIM_FLAG_Update);          recvStat2++;         if(recvStat2 == COM_STOP_BIT)         {             TIM_Cmd(TIM5, DISABLE);             USART2_buf[len2++] = recvData2;         if(len2 > Recive2_Byte-1)         {             len2 = 0;             USART2_Send(USART2_buf,Recive2_Byte);         }             return;         }         if(OI2_RXD)         {             recvData2 |= (1 << (recvStat2 - 1));         }else{             recvData2 &= ~(1 << (recvStat2 - 1));         }    }   }vuart2.h#ifndef __VUART2__H #define __VUART2__H #include "stm32f10x.h"  void IO2_TXD(u8 Data); void USART2_Send(u8 *buf, u8 len); void IO2Config(void); void TIM5_Int_Init(u16 arr,u16 psc); #endif
  本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

孩子突然愣神,一查竟然是癫痫!出现这些症状,赶紧去医院!如果你走在街上看到有人突然倒地全身抽搐口吐白沫意识丧失大多数人很快可以反应过来这多半是癫痫发作了然而你可能不知道的是一些看似很正常的小动作也可能是癫痫作怪01hr孩子突然愣神要警惕我们小时候常挨打骂,却少有问题为啥现在孩子动不动就抑郁症?最近常听到有些父母在抱怨,为什么我们小时候经常挨骂挨打,大多数人也没有什么严重的心理问题,但现在的孩子却如此脆弱,一个个玻璃心的不行呢?好像确实有点难以理解,相对于咱们那一代,这届戏剧体验对孩子意味着什么?聪明的孩子都在这里玩与学!关于我们索石艺术专注于儿童科普事业,通过戏剧教育来开发孩子在成长过程中能促进的八种能力感觉能力运动能力交际能力创造能力感情能力精神能力社交能力知识能力,这些能力就是戏剧教育带来的多2022年苏州新生儿爆款名字出炉!近日,苏州市公安局公布了2022年苏州新生儿爆款名字,看看宝爸宝妈们都爱取哪些名字,有没有你家同款呀?2022年新生男宝使用最多的10个名字基于2022年落户新生男宝的数据,取名最宣扬功利性内容,励志演讲切莫误人子弟徐林生2月19日上午,一则题为合肥教育名师陈某某讲座中被学生轰下台的视频图文网帖在微博抖音等多个网络平台上广为流传。据网帖介绍,2月18日下午,合肥师范学院副教授陈某某在安徽省庐江世纪华通两项公益成果即将发布助力青少年健康上网中证网讯(记者王奕斐)以网络游戏为应用场景,世纪华通宣布即将发布两项重要的公益成果。日前,由中国音像与数字出版协会指导,人民网主办的2022游戏公益盛典在广州举办。世纪华通盛趣游戏二月二龙抬头,营养师提醒猪头肉选对部位吃才健康2月21日迎来二月二,龙抬头。很多市民会在这一天吃猪头肉。那么,猪头肉能不能多吃?又是否有营养呢?哈尔滨市红十字中心医院围产保健门诊营养师孙玉红表示,猪头肉选对部位吃才健康。猪头肉狄耐克五恒智能新风系统多维智控,营造健康舒居DNAKE狄耐克消费理念与健康观念升级,住宅不再是冰冷的建筑载体,而是健康舒适的美好人居关系的缩影,健康住宅将成为住房消费刚需,健康舒适是古今中外亘古不变的追求。狄耐克智能新风系统跨国企业在中国丨美敦力上海工厂常年全球最佳,加速推进本土化造福更多中国患者在首届中国国家进口博览会上,因展出全世界最小心脏起搏器,医疗企业美敦力的名字逐渐为大众所知。事实上,早在1989年,美敦力就在上海设立办事处,成为首批进入中国的跨国医疗科技企业之一自闭症儿童的行为表现有哪些?这几个症状,家长要警惕了自闭症是一种常见的儿童发育障碍疾病,其主要临床症状包括社会交往障碍交流障碍兴趣狭窄和僵硬重复的行为。自闭症儿童通常在三岁前就会表现异常,自闭症是障碍在儿童发育的不同时期表现不同,但腿出现这些症状,或说明你的血脂太高了,赶快去医院检查根据人们日常饮食的变化,我们可以看出,近年来,我国国民的生活水平确实得到了极大的改善。可富足的物质生活,虽然给人们带来了极大的幸福感,可大鱼大肉的生活,同时也给人们带来了一定的健康
颜骏凌挽狂澜于既倒,莱科错用一人险丢胜局,哈维尔却笑了面对河南嵩山龙门的残阵,上半场已经两球领先,下半场更是把裁判无中生有的点球扑出,此时人们皆认为胜负毫无悬念了,可是剧情却逆转了。球迷说若不是颜骏凌开挂般的表现,四次扑出必进球,挽狂小米新机官宣9月27日,正式发布从目前来看,9月份作为近几个月新机发布量最少的一个月,主要是苹果华为发布了旗舰机,其它手机品牌基本选择了让路,毕竟二大旗舰机无论是芯片还是系统都有一定的优势,实在是很难竞争,所以各国产电视剧飞天标上线!设计真的很赞9月21日,广电总局发布通知。为适应新时代电视剧高质量发展需要,进一步提升电视剧制作规范化标准化水平,打造中国电视剧的标志性文化符号,自2022年9月21日起,国产电视剧将启用统一新研究估算全球蚂蚁总数约2亿亿只蚂蚁是一种常见的昆虫,那地球上到底有多少只蚂蚁呢?一项最新的科学研究给出的估算结果是至少有2亿亿只。德国维尔茨堡大学中国香港大学等机构的研究人员在最新一期美国国家科学院学报上发表论敌方秒选钟无艳怎么办?别用亚瑟,放弃芈月,他让钟无艳不敢出塔在王者荣耀中战士类英雄越来越受玩家们的欢迎,其实还是因为战士的整体强度提升了,虽然战士基本上都是打上单的位置,但是一名会玩上单的玩家,前期就可以在线上打出优势,之后可以快速游走支援3。0须弥版本108个草神瞳路线(已完结)草神瞳共108个(建议做完森林书全篇开始)(森林书任务会解锁任务道具梦之树一些传送点和神像也是目前最阴间的任务)道成林和护世森p326个神瞳红色标点121(直接或解密获取)黑色标点原神的反作弊驱动被勒索软件利用杀死杀毒软件原神的反作弊驱动被勒索软件利用杀死杀毒软件安全公司趋势科技的研究人员报告,原神的反作弊驱动mhyprot2。sys被勒索软件利用杀死杀毒软件的进程和服务。mhyprot2。sys作58连线将在中超上演!海港官方巴尔加斯正式加盟北京时间8月30日,上海海港官方宣布,阿根廷前锋马蒂亚斯巴尔加斯正式加盟,他与武磊的58连线将在中超上演。附海港官宣官宣阿根廷前锋马蒂亚斯巴尔加斯正式加盟上海海港足球俱乐部经友好协关窗前的疯狂!大连人继续官宣新外援博桑季奇加盟北京时间8月30日,大连人继续官方宣布新外援加盟,与塞尔维亚球员内马尼亚博桑季奇达成一致,后者正式加盟。附大连人官宣经与球员友好协商,塞尔维亚球员内马尼亚博桑季奇(NemanjaB挖海河挖海河杨金山海河是个工程浩大的总称,分别有相当多的支干,起到防洪排洪水作用,在六七十年代,伟人毛主席号召一定要根治海河,千軍万马齐上阵,迅速掀起挖海河高潮。在那个年代人们生活还很差洗冤还是洗白?梅西续约巴萨邮件被曝,拉波尔塔的心思路人皆知接连撬动4个杠杆,拉波尔塔成为今夏转会窗最靓的仔,巴萨也一改此前虎落平阳的落魄模样,重新焕发了活力。改头换面的巴萨,可以说是欧洲足坛势头最猛的球队之一。西甲6轮5胜1平,进18球失