分享

day03

 goodwangLib 2022-03-13

1、在stm32F4中,有8个串口,分别挂载在高级外设总线上APB1和APB2上,在APB1(42MHz)上有USART2、USART3、UART4、UART5、UART7、UART8;

  在APB2(84MHz)总线上,挂载有USART1、USART6;

   从上面的时钟来看,USART1和USART6速度最高,可以达到10M/bits的传输速率。

2、串口配置步骤:

  1、分别使能对应的GPIO时钟,使能相关的串口时钟;

  2、配置复用映射器,将GPIO与USART1关联起来;

  3、初始化GPIO,管脚模式需要设置为复用模式

  4、串口初始化,设置相关的参数,波特率、数据位长度、校验位等(8N1);

  5、打开串口;

  6、如果使能串口接收中断;

  7、配置中断优先级;

  8、编写中断处理函数;(每处理完一次8N1的数据后,下一次数据来都会触发一次中断)

   上面的USART1_Tx  PA9表示PA9可以常用复用为USART1_TX功能;

3、看一下具体的串口配置代码;

  1、进行基本配置:

复制代码
 1 u8 USART_RX_BUF[USART_REC_LEN];     //
 2 
 3 u16 USART_RX_STA=0;       // bit15 位接收完成标志,接收到了0x0A;bit14位接收到了0x0D;
 4 
 5 void uart_init(u32 bound){
 6     GPIO_InitTypeDef GPIO_InitStructure;
 7     USART_InitTypeDef USART_InitStructure;
 8     NVIC_InitTypeDef NVIC_InitStructure;
 9 
10         // 1、配置GPIO、USART1外设时钟    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); // GPIO时钟初始化    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//USART1时钟初始化
11 
12     // 2、配置复用映射器    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9 复用为USART1串口功能
13     GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10 ---》USART1
14 
15     // GPIO参数初始化
16     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9  GPIOA10
17     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//  配置复用模式
18     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz
19     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //
20     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //­
21     GPIO_Init(GPIOA,&GPIO_InitStructure); //
22 
23     //USART1 参数初始化 
24     USART_InitStructure.USART_BaudRate = bound;//
25     USART_InitStructure.USART_WordLength = USART_WordLength_8b;//
26     USART_InitStructure.USART_StopBits = USART_StopBits_1;//
27     USART_InitStructure.USART_Parity = USART_Parity_No;
28     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
29     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //
30     USART_Init(USART1, &USART_InitStructure); //  串口初始化
31         // 打开串口
32     USART_Cmd(USART1, ENABLE);  //
33 
34     //USART_ClearFlag(USART1, USART_FLAG_TC);
35 
36 #if EN_USART1_RX    
37     //#if 1
38     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//   打开串口中断
39     //Usart1 NVIC  配置串口中断的优先级
40     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//
41       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//
42     NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;        
43     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            
44     NVIC_Init(&NVIC_InitStructure);    
45 
46 #endif
47     
48 }    
View Code
复制代码

  2、串口中断函数:这里轻微加了一点协议,对接受到的数据判断。对后面两位数据

复制代码
 1 void USART1_IRQHandler(void)                    //
 2 {
 3     u8 Res;
 4         // 接收数据中断判断
 5     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
 6     {
 7         Res =USART_ReceiveData(USART1);//(USART1->DR);    // 读取数据
 8         
 9         if((USART_RX_STA&0x8000)==0)// 判断是否接受到0x0A 结束数据是否完成
10         {
11             if(USART_RX_STA&0x4000)//0x0d
12             {
13                 if(Res!=0x0a)USART_RX_STA=0;//数据接收异常
14                 else USART_RX_STA|=0x8000;    //数据接收完成
15             }
16             else //0X0D
17             {    
18                 if(Res==0x0d)USART_RX_STA|=0x4000;
19                 else
20                 {
21                     USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;  // 接收到的数据保存起来
22                     USART_RX_STA++;
23                     if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//   
24                 }         
25             }
26         }            
27   } 
28 
29 } 
View Code
复制代码

  3、主函数

复制代码
 1 int main(void)
 2 {
 3     
 4     u8 len,t;
 5     u16 times;
 6     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 7     delay_init(168);          
 8     LED_Init();              
 9     UsartInit(115200);
10 
11     LED0 = 0;
12     printf('my uart init...');
13     
14     while(1)
15     {
16         if(USART_RX_STA&0x8000)
17         { 
18             len=USART_RX_STA&0x3fff;//????????????
19             printf('\r\nYou input info: \r\n');
20             for(t=0;t<len;t++)
21             {
22                 USART1->DR=USART_RX_BUF[t];
23                 while((USART1->SR&0X40)==0);
24             }
25             printf('\r\nprint over from USART1... \r\n');//
26             USART_RX_STA=0;
27         }else
28         {
29             times++;
30             if(times%5000==0)
31             { printf('\r\n ALIENTEK STM32F407 \r\n');
32                 printf(' hello@ALIENTEK\r\n\r\n\r\n');
33             }
34             if(times%200==0)printf('Please input data: \r\n'); 
35             if(times%30==0)LED0=!LED0;//
36             delay_ms(10); 
37         }
38 
39     
40     }
41     
42 }
View Code
复制代码

  4、print函数依赖代码:

复制代码
// USART1
//重定义  printf函数最终调用这个函数,因此使用不同串口时,需要修改这块的函数
int fputc(int ch, FILE *f)
{     
    while((USART1->SR&0X40)==0);
    USART1->DR = (u8) ch;      
    return ch;
}
View Code
复制代码

完成上面的代码后,尝试使用USART2进行试验,后面可以再使用UART4实验

4、对上面的代码简单修改后

复制代码
 1 //主函数和上面差不读
 2 
 3 // USART2初始化
 4 void UsartInit(u32 baund)
 5 {
 6     // 
 7     GPIO_InitTypeDef  GPIO_InitStructure;   // 
 8     USART_InitTypeDef USART_InitStructure;  // 
 9     NVIC_InitTypeDef  NVIC_InitStructure;   // 
10     
11     // 
12     // 
13     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,  ENABLE);    
14     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);// 
15     
16     // 2 
17     GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
18     GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); 
19     
20     //
21     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;// 
22   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;               // 
23   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;             //
24   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //100MHz   
25   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// 
26   GPIO_Init(GPIOA, &GPIO_InitStructure);//GPIO
27     
28     //  uart
29     USART_InitStructure.USART_BaudRate = baund;
30     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
31     USART_InitStructure.USART_Parity = USART_Parity_No;
32     USART_InitStructure.USART_StopBits = USART_StopBits_1;
33     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
34     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
35     
36     USART_Init(USART2, &USART_InitStructure);  // UART1
37     USART_Cmd(USART2 ,ENABLE);    // 
38     
39     // 
40     USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);  // 
41     
42     NVIC_InitStructure.NVIC_IRQChannel =  USART2_IRQn;   // stm32F4xx.h 
43     NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;
44     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
45     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
46     
47     NVIC_Init(&NVIC_InitStructure);   // ³õʼ»¯ÖжÏÓÅÏȼ¶
48     
49 
50 }
51 
52 
53 
54 // USART2 中断服务函数
55 void USART2_IRQHandler(void)                    
56 {
57     u8 Res;
58 
59     if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  
60     {
61         Res =USART_ReceiveData(USART2);//(USART1->DR);    
62         
63         if((USART_RX_STA&0x8000)==0)
64         {
65             if(USART_RX_STA&0x4000)//
66             {
67                 if(Res!=0x0a)USART_RX_STA=0;//
68                 else USART_RX_STA|=0x8000;    // 
69             }
70             else //0X0D
71             {    
72                 if(Res==0x0d)USART_RX_STA|=0x4000;
73                 else
74                 {
75                     USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
76                     USART_RX_STA++;
77                     if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//  
78                 }         
79             }
80         }            
81   } 
82 } 
83 
84 
85 // printf在USART2下依赖函数
86 // USART2
87 int fputc(int ch, FILE *f)
88 {     
89     while((USART2->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
90     USART2->DR = (u8) ch;      
91     return ch;
92 }
View Code
复制代码

测试均正常;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多