[应用相关] 【转】stm32发送中断编程思路

[复制链接]
1066|11
 楼主| xia00 发表于 2016-10-22 10:28 | 显示全部楼层 |阅读模式
u8 TxBuffer[2];
u8 TxCounter=0;
u8 count=0;
void USART_SendData_Int(u8 *str)
{
        while(*str != '\0')
        {
                TxBuffer[count++] = *str++;
        }  
        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);        
}
void delay(void)
{
        long i,j;
        for(i=0;i<1500;i++)
                for(j=0;j<2000;j++);
}
int main(void)
{
    USART_Configuration();
    NVIC_Configuration();

    while (1)
    {
          USART_SendData_Int("012345678901234567890123456789012345\n");        
          USART_SendData_Int("abcdefghijklmn\n");
          delay();   
    }
}
void USART_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);                  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;               
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_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;

  USART_Init(USART1, &USART_InitStructure);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_ITConfig(USART1, USART_IT_TXE, DISABLE);        
  USART_ClearFlag(USART1,USART_FLAG_TC);
  USART_Cmd(USART1, ENABLE);
}
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;

        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
void USART1_IRQHandler(void)
{

  if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
  {   

    USART_SendData(USART1, TxBuffer[TxCounter++]);                    


    USART_ClearITPendingBit(USART1, USART_IT_TXE);

    if(TxCounter == count)
    {

      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    }   
  }
}

这个程序经过调试,在串口调试助手上一点问题都没有!!!不过似乎从程序上看问题很多:1、我定义的串口缓存TxBuffer[2],为什么大小只有两个字节(应该说是任意字节大小都可以),我程序在发送数据时,数据大小远远超过两个字节,但是却没报错,更是还能正确运行。。。没懂!?2、我定义的两个全局变量u8 TxCounter=0;u8 count=0;每发送一次数据,都会相应自加上数据的长度,程序中没有对其清零, 却似乎永远没有溢出的迹象。怎么解释?
feiqi1 发表于 2016-10-22 10:32 | 显示全部楼层
查询方式:发送数据——先发后查;

                     接收数据——先查后收。
androidbus 发表于 2016-10-22 10:39 | 显示全部楼层
中断处理函数如下

void USART1_IRQHandler(void)
{
    if( USART_GetITStatus(USART1, USART_IT_TC) == SET  )
    {
        if( *pDataByte == '\0' )//TC需要 读SR+写DR 方可清0,当发送到最后,到'\0'的时候用个if判断关掉
            USART_ClearFlag(USART1, USART_FLAG_TC);//不然TC一直是set, TCIE也是打开的,导致会不停进入中断. clear掉即可,不用关掉TCIE
        else
            USART_SendData(USART1, *pDataByte++ );
    }

}

其中u8 *pDataByte;是一个外部指针变量
litengg 发表于 2016-10-22 10:40 | 显示全部楼层
在中断处理程序中,发送完该字符串后,不用关闭TC的中断使能TCIE,只需要清掉标志位TC吧
qiangweii 发表于 2016-10-22 10:46 | 显示全部楼层
Tramsimssion Complete后,才产生中断. 开TC中断必须放在这里,否则还是会丢失第一字节。。。
shashaa 发表于 2016-10-22 10:51 | 显示全部楼层
在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器,另一个是程序看不到的移位寄存器。
 楼主| xia00 发表于 2016-10-22 10:54 | 显示全部楼层
总的来说,STM32单片机的串口还是很好理解的,编程也不算复杂。当然我更愿意希望其中断系统和51单片机一样的简单。
hfdy01 发表于 2016-10-22 11:00 | 显示全部楼层
对于接收终端,就是RXNE了,这只在接收完成后才产生。
643757107 发表于 2016-10-22 11:06 | 显示全部楼层
没有报错应该是指针起到了一定的作用。
CallReceiver 发表于 2016-10-22 11:13 | 显示全部楼层
对于发送,切记需要注意TXE和TC的差别。。
sourceInsight 发表于 2016-10-22 11:25 | 显示全部楼层
可以和串口调试助手上对比看看吧
Listate 发表于 2016-10-22 14:06 | 显示全部楼层
为什么大小只有两个字节??什么原因,楼主问题解决了吗??
您需要登录后才可以回帖 登录 | 注册

本版积分规则

179

主题

1867

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部