你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F1串口配置经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-14 16:33
步骤如下所示:
步骤一:使能串口时钟及GPIO端口时钟
步骤二:GPIO端口模式设置,设置串口对应的引脚为复用功能
步骤三:初始化串口参数,包含波特率、字长、奇偶校验等参数
步骤四:使能串口
步骤五:设置串口中断类型并使能
步骤六:设置串口中断优先级,使能串口中断通道
步骤七:编写串口中断服务函数


  1. #include "sys.h"
  2. #include "usart.h"          
  3. //          
  4. //如果使用ucos,则包括下面的头文件即可.
  5. #if SYSTEM_SUPPORT_UCOS
  6. #include "includes.h"                                        //ucos 使用          
  7. #endif


  8. unsigned char ucRxFinish=0;
  9. static unsigned char ucCnt=0,ucLen=0;
  10. unsigned char ucRxData[100];

  11. //
  12. //加入以下代码,支持printf函数,而不需要选择use MicroLIB          
  13. #if 1
  14. #pragma import(__use_no_semihosting)            
  15. //标准库需要的支持函数                 
  16. struct __FILE
  17. {
  18.         int handle;

  19. };

  20. FILE __stdout;      
  21. //定义_sys_exit()以避免使用半主机模式   
  22. _sys_exit(int x)
  23. {
  24.         x = x;
  25. }
  26. //重定义fputc函数
  27. int fputc(int ch, FILE *f)
  28. {      
  29.         while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
  30.     USART1->DR = (u8) ch;      
  31.         return ch;
  32. }
  33. #endif

  34. /*使用microLib的方法*/
  35. /*
  36. int fputc(int ch, FILE *f)
  37. {
  38.         USART_SendData(USART1, (uint8_t) ch);

  39.         while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}       
  40.    
  41.     return ch;
  42. }
  43. int GetKey (void)  {

  44.     while (!(USART1->SR & USART_FLAG_RXNE));

  45.     return ((int)(USART1->DR & 0x1FF));
  46. }
  47. */

  48. #if EN_USART1_RX   //如果使能了接收
  49. //串口1中断服务程序
  50. //注意,读取USARTx->SR能避免莫名其妙的错误          
  51. u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
  52. //接收状态
  53. //bit15,        接收完成标志
  54. //bit14,        接收到0x0d
  55. //bit13~0,        接收到的有效字节数目
  56. u16 USART_RX_STA=0;       //接收状态标记          
  57.   
  58. void uart_init(u32 bound)
  59. {
  60.     //GPIO端口设置
  61.     GPIO_InitTypeDef GPIO_InitStructure;
  62.         USART_InitTypeDef USART_InitStructure;
  63.         NVIC_InitTypeDef NVIC_InitStructure;
  64.          
  65.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟
  66.      //USART1_TX   PA.9
  67.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  68.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  69.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  70.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  71.    
  72.     //USART1_RX          PA.10
  73.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  74.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  75.     GPIO_Init(GPIOA, &GPIO_InitStructure);  

  76.    //Usart1 NVIC 配置

  77.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  78.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  79.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
  80.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
  81.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
  82.   
  83.    //USART 初始化设置

  84.         USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
  85.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  86.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  87.         USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  88.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  89.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

  90.     USART_Init(USART1, &USART_InitStructure); //初始化串口
  91.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
  92.     USART_Cmd(USART1, ENABLE);                    //使能串口

  93. }

  94. void USART1_IRQHandler(void)                        //串口1中断服务程序
  95. {
  96.         u8 Res;
  97. #ifdef OS_TICKS_PER_SEC                 //如果时钟节拍数定义了,说明要使用ucosII了.
  98.         OSIntEnter();   
  99. #endif
  100.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  101.         {
  102.                 Res =USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
  103.                
  104.                 if((USART_RX_STA&0x8000)==0)//接收未完成
  105.                 {
  106.                         if(USART_RX_STA&0x4000)//接收到了0x0d
  107.                         {
  108.                                 if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
  109.                                 else USART_RX_STA|=0x8000;        //接收完成了                         //bit31表明是否接收到0x0a(\n)
  110.                         }
  111.                         else //还没收到0X0D
  112.                         {       
  113.                                 if(Res==0x0d)USART_RX_STA|=0x4000;                                                //bit30表明是否接收到0x0d(\r)
  114.                                 else
  115.                                 {
  116.                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
  117.                                         USART_RX_STA++;
  118.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收          
  119.                                 }                 
  120.                         }
  121.                 }                    
  122.    }
  123. #ifdef OS_TICKS_PER_SEC                 //如果时钟节拍数定义了,说明要使用ucosII了.
  124.         OSIntExit();                                                                                           
  125. #endif
  126. }
  127. #endif       






  128. void USART2_Init(u32 bound){
  129.     //GPIO端口设置
  130.         GPIO_InitTypeDef GPIO_InitStructure;
  131.         USART_InitTypeDef USART_InitStructure;
  132.         NVIC_InitTypeDef NVIC_InitStructure;
  133.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
  134.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);        //使能USART2,GPIOA时钟
  135.         USART_DeInit(USART2);  //复位串口2
  136.         //USART2_TX   PA.2
  137.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
  138.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  139.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  140.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
  141.    
  142.     //USART2_RX          PA.3
  143.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  144.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//浮空输入
  145.         GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10

  146.    //Usart2 NVIC 配置

  147.         NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  148.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  149.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;                //子优先级3
  150.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
  151.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
  152.   
  153.    //USART 初始化设置
  154.         USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
  155.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  156.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  157.         USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  158.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  159.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

  160.         USART_Init(USART2, &USART_InitStructure); //初始化串口
  161.         USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断
  162.         USART_Cmd(USART2, ENABLE);                    //使能串口

  163. }




  164. void USART2_IRQHandler(void)                        //串口1中断服务程序
  165. {
  166.         unsigned char temp=0;
  167.   u16 C=0;

  168. //        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  
  169. //                {
  170. //                  temp=USART_ReceiveData(USART2);
  171. //                       
  172. //                        if(ucCnt==0)
  173. //                                        ucRxData[ucCnt++]=temp;
  174. //                  else        if((ucCnt==1)&(temp==0x03))
  175. //                                        ucRxData[ucCnt++]=temp;
  176. //                        else if(ucCnt==2)
  177. //                                        {ucRxData[ucCnt++]=temp; ucLen=ucRxData[2];}
  178. //                        else if((ucCnt>2)&(ucCnt<=(ucLen+4)))
  179. //                                        ucRxData[ucCnt++]=temp;
  180. //                        if(ucCnt==(ucLen+5))
  181. //                        {  C=ModbusCRC(ucRxData,ucLen+3);
  182. //                                if(C==((ucRxData[ucLen+3]<<8)|ucRxData[ucLen+4]))
  183. //                                        {ucRxFinish=1;        ucCnt=0;ucLen=0;}                       
  184. //                                else
  185. //                                        {ucCnt=0;ucLen=0;}                               
  186. //                        }
  187. //                       
  188. //                }
  189.           USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  190. }                    

  191.        

  192. void USART2_Send(unsigned char *data,uint8_t ucLen)
  193. {
  194.         uint8_t i;
  195.         USART_ClearFlag(USART2,USART_FLAG_TC);
  196.         for(i=0;i<ucLen;i++)
  197.         {
  198.                 USART_SendData(USART2,*(data+i));
  199.                 while(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);
  200.         }
  201. }

  202. uint16_t ModbusCRC(uint8_t *ptr,uint16_t ucLen)//CRC校验
  203. {
  204.         uint8_t i;
  205.         uint16_t j,crc=0xffff;
  206.         uint16_t n;
  207.         i=i;       
  208.        
  209.         for(n=0;n<ucLen;n++)
  210.         {
  211.                 crc=ptr[n]^crc;
  212.                 for(i=0;i<8;i++)
  213.                 if(crc&0x01)
  214.                 {
  215.                         crc=crc>>1;
  216.                         crc=crc^0xa001;
  217.                 }
  218.                 else
  219.                 {
  220.                         crc=crc>>1;       
  221.                 }               
  222.         }

  223.         j=crc>>8;
  224.         j=j|(crc<<8);
  225.         return j;

  226. }







  227. void usart3_init(u32 bound)          //串口初始化函数
  228. {  

  229.          GPIO_InitTypeDef GPIO_InitStructure;
  230.          USART_InitTypeDef USART_InitStructure;
  231.          NVIC_InitTypeDef NVIC_InitStructure;
  232. // 串口时钟使能   
  233.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOB时钟
  234.          RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能
  235. //串口复位
  236.          USART_DeInit(USART3);  //复位串口3
  237. //USART3_TX    GPIOB10
  238.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    //PB10
  239.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  240.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  241.           GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
  242. //USART3_RX   GPIOB11
  243.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;   //PB11
  244.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  245.           GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
  246. //USART 初始化设置
  247.           USART_InitStructure.USART_BaudRate = bound;//串口波特率
  248.           USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  249.           USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  250.           USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  251.           USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  252.           USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  253.              USART_Init(USART3, &USART_InitStructure); //初始化串口3
  254. //Usart3  NVIC 配置
  255.          NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;       //串口3的中断
  256.          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  257.          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;     //子优先级3
  258.          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       //IRQ通道使能
  259.          NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  260. //开启中断         
  261.          USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
  262. //使能串口   
  263.                 USART_Cmd(USART3, ENABLE);                    //使能串口3
  264.   }

  265.   void USART3_IRQHandler(void)                 //串口3中断服务程序
  266. {
  267.         u8 ReceiveData ;
  268.         if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断
  269.           {
  270.                   ReceiveData =USART_ReceiveData(USART3); //读取接收到的数据
  271.         }
  272. }


复制代码
  1. int main(void)
  2. {               
  3.     uint16_t c=14;
  4. //        Init_HX711pin();
  5.         delay_init();
  6.        
  7.         NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  8. //    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  9.         uart_init(9600);         //串口初始化
  10.     USART2_Init(9600);
  11.         usart3_init(9600);    //波特率设置为9600
  12. //        Get_Maopi();                                //称毛皮重量
  13.         delay_ms(1000);
  14.         delay_ms(1000);
  15. //        Get_Maopi();                                //重新获取毛皮重量
  16.        
  17.         while(1)
  18.         {
  19. //                Get_Weight();

  20. //                printf("净重量 = %d g\r\n",Weight_Shiwu); //打印
  21. //                delay_ms(1000);
  22. //        
  23.         USART2_Send("9999",4);
  24.         delay_ms(1000);

  25.         USART_SendData(USART3,68);    //串口发送数据

  26.         }
  27. }

复制代码

————————————————
版权声明:qmy_lhl
如有侵权请联系删除


收藏 评论0 发布时间:2023-5-14 16:33

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版