OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 15658|回复: 5

USART串口超时中断(想尝试不要输入回车键)

[复制链接]

8

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2012-7-21
在线时间
0 小时
发表于 2012-7-21 21:56:50 | 显示全部楼层 |阅读模式

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    #ifdef  VECT_TAB_RAM 
      
       NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else 
      
       NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
    #endif
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
   
            
    NVIC_InitStructure.NVIC_IRQChannel =  USART1_IRQn;; 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void GPIO_Configuration(void)
{
 
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void USART_Configuration(void)
{
    USART_InitStructure.USART_BaudRate = 9600;                                   //
波特率9600
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //
字长8
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                  //1
位停止字节
    USART_InitStructure.USART_Parity = USART_Parity_No;                    //
无奇偶校验
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//
无流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//
打开Rx接收和Tx发送功能
    USART_Init(USART1, &USART_InitStructure);                                          //
初始化
   
   
    USART_Cmd(USART1, ENABLE);                                                        //
启动串口
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
 USART_ITConfig(USART1, USART_FLAG_TC, ENABLE);
}

void RCC_Configuration(void)    //
时钟初始化函数
{
    ErrorStatus HSEStartUpStatus;     //
等待时钟的稳定
    RCC_DeInit();         //
时钟管理重置
    RCC_HSEConfig(RCC_HSE_ON);      //
打开外部晶振
    HSEStartUpStatus = RCC_WaitForHSEStartUp(); //
等待外部晶振就绪
    if (HSEStartUpStatus == SUCCESS)
    {
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//flash
读取缓冲,加速
        FLASH_SetLatency(FLASH_Latency_2); //flash
操作的延时
        RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB
使用系统时钟
        RCC_PCLK2Config(RCC_HCLK_Div2);  //APB2
(高速)为HCLK的一半
        RCC_PCLK1Config(RCC_HCLK_Div2);  //APB1
(低速)为HCLK的一半
        //
注:AHB主要负责外部存储器时钟。PB2负责ADI/O,高级TIM,串口1APB1负责DAUSBSPII2CCAN,串口2345,普通TIM
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
  //PLLCLK = 8MHz * 9 = 72 MHz
        RCC_PLLCmd(ENABLE);     //
启动PLL
        while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};//
等待PLL启动
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//
PLL设置为系统时钟源
        while (RCC_GetSYSCLKSource() != 0x08){}//
等待系统时钟源的启动
    }
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1| RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA, ENABLE );
}

 

 

SysTick_Config()函数的参数配置,SysTick时钟配置

void SysTick_Configuration(void)
{
           
            if (SysTick_Config((SystemCoreClock) / 10))    //     1/10s=100ms
            {
                     
                     while (1);
            }

           NVIC_SetPriority(SysTick_IRQn, 0x0);
}

SysTick_Config(SystemFrequency / 10)   函数的形参就是systick重装定时器的值。
systck计数频率为每秒72000000次,所以7200000次就是1/10秒,也就是100ms

SysTick124bit递减计数器,通过对SysTick控制与状态寄存器的设置,可选择HCLK时钟(72M)HCLK8分频(9M,缺省是这个)作为SysTick的时钟源。
SysTick的重装寄存器决定了定时器频率。

SysTick的时钟源是72M,   SystemFrequency = 72000000Hz
所以 SysTick_Config(SystemFrequency / 1000) 就是1ms时基。
//     1/1000 s=1ms

void USART1_IRQHandler(void)
{  
    uint8_t i;
    if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
 {      
       RxTimeOut=3;//
字符串超时等待时间;3毫秒;
       i = USART_ReceiveData(USART1);//
接收下一个字符
       data[f]=i;
       USART_SendData(USART1,data[f]); 
       while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {}; 
       f=f+1;
       if (f==32) {f=33;flag=1;} //32
个数据接收完成,flag1f进入空闲状态 

 }
    if(USART_GetITStatus(USART1, USART_IT_RXNE) == RESET)
 {
         
          USART_ClearITPendingBit(USART1, USART_IT_RXNE);
 }
 
}


void SysTick_Handler(void)
{
    if(RxTimeOut>0)  RxTimeOut--;
 else    f=33; //
超时进入空闲状态
}
这是用库函数版本的,不知道用寄存器怎么改写串口中断服务程序?求各位大侠帮忙

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-7-22 01:43:43 | 显示全部楼层
回复【楼主位】mimi:
---------------------------------
可以用定时器,来判断结束.
比如只要收到1个字符,就清零定时器,然后只要定时器的计数超过一定的时间,就认为接收完成了.
比如9600的波特率,大概1ms发送1个字节,那么你可以设定超时时间为10ms,如果连续10ms没有收到数据,则认为接收完成了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2013-1-14
在线时间
0 小时
发表于 2013-1-14 16:46:02 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原子哥,有程序吗?我正在头痛这个呢,能发一个给我参考一下吗?用寄存器写的!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-1-14 17:12:53 | 显示全部楼层
暂时还没
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2013-1-14
在线时间
0 小时
发表于 2013-1-14 17:19:14 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
原子哥,寄存器编程怎么设置SysTick中断的优先级啊?搞不定啊,我现在做的项目是接收传感器的数据没有什么结束标志,现在考虑用超时判断。
回复 支持 反对

使用道具 举报

3

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
104
金钱
104
注册时间
2012-12-25
在线时间
3 小时
发表于 2013-1-14 20:38:19 | 显示全部楼层
如果需要,楼主可以发邮件给我,celticzy@gmail.com,目前有份现成的,也经过实践,不需要用到硬件定时器,毕竟一个串口分配一个定时器太浪费,不过要用到软件定时器,由systick实现。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-21 11:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表