OpenEdv-开源电子网

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

一个一个字节发送数据,使用串口发送中断

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2012-10-30
在线时间
0 小时
发表于 2012-12-12 10:58:31 | 显示全部楼层 |阅读模式
我想一个一个字节发送数据,使用串口发送中断,在发送区不空时不能往DR写数据,在DR中的字节发送完成及发送区空中断来时继续在DR中谢数据,请教原子如何实现?我在例子程序上开放了发送完成及发送区空中断后,在中断函数里继续填DR,用你的串口监测程序看,数据传送不正常,基本都是乱的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-12 11:13:06 | 显示全部楼层
数据是乱的,说明你的波特率不匹配,或者你发送的数据不是ASCII的,你检查下是数据设置的问题,还是波特率设置的问题。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2012-10-30
在线时间
0 小时
 楼主| 发表于 2012-12-12 11:46:19 | 显示全部楼层
确实不是ASCII码,源码如下:
(*波特率是对的,如果发送采用非中断方式通讯是正常的,使用中断方法老是死在中断中*)
void uart_init(u32 pclk2,u32 bound)
{    
float temp;
u16 mantissa;
u16 fraction;    
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp;  //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分  
    mantissa<<=4;
mantissa+=fraction; 
RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
RCC->APB2ENR|=1<<14;  //使能串口时钟 
GPIOA->CRH&=0XFFFFF00F; 
GPIOA->CRH|=0X000008B0;//IO状态设置
  
RCC->APB2RSTR|=1<<14;   //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位        
//波特率设置
  USART1->BRR=mantissa; // 波特率设置  
USART1->CR1|=0X200C;  //1位停止,无校验位.

//使能接收中断
USART1->CR1|=1<<8;    //PE中断使能
USART1->CR1|=1<<5;    //接收缓冲区非空中断使能
//USART1->CR1|=3<<6;  
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级 

}


void USART1_IRQHandler(void)
{
u8 res;     
if(USART1->SR&(1<<5))//接收到数据
{
   res=USART1->DR;
   if(InQueueInx>=UART_BUF_SIZE)  
   {
      InQueueInx=0;
   }
   USART_RX_BUF[InQueueInx]=res;
   InQueueInx++;
   
       

 #if 1
if(USART1->SR&(1<<6))//发送区数据已经为空
{
   //USART1->SR&=~(1<<6); 
   if(TX_OutQueueInx==TX_InQueueInx)
   {

   //USART1->SR&=~(1<<6); 
     return;
   }
   USART1->DR=USART_TX_BUF[TX_OutQueueInx];
   TX_OutQueueInx++;
    if(TX_OutQueueInx>=UART_BUF_SIZE) 
     TX_OutQueueInx =0;

   USART1->SR&=~(1<<6); 

#endif  
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2012-10-30
在线时间
0 小时
 楼主| 发表于 2012-12-12 11:49:09 | 显示全部楼层
确实不是ASCII码,源码如下: 
(*波特率是对的,如果发送采用非中断方式通讯是正常的,使用中断方法老是死在中断中,折腾死了,要向你请教下面哪边有问题*) 
void uart_init(u32 pclk2,u32 bound) 
{     
float temp; 
u16 mantissa; 
u16 fraction;     
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV 
mantissa=temp;  //得到整数部分 
fraction=(temp-mantissa)*16; //得到小数部分   
    mantissa<<=4; 
mantissa+=fraction;  
RCC->APB2ENR|=1<<2;   //使能PORTA口时钟   
RCC->APB2ENR|=1<<14;  //使能串口时钟  
GPIOA->CRH&=0XFFFFF00F;  
GPIOA->CRH|=0X000008B0;//IO状态设置 
   
RCC->APB2RSTR|=1<<14;   //复位串口1 
RCC->APB2RSTR&=~(1<<14);//停止复位         
//波特率设置 
  USART1->BRR=mantissa; // 波特率设置   
USART1->CR1|=0X200C;  //1位停止,无校验位. 

//使能接收中断 
USART1->CR1|=1<<8;    //PE中断使能 
USART1->CR1|=1<<5;    //接收缓冲区非空中断使能 
USART1->CR1|=3<<6;   
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级  




void USART1_IRQHandler(void) 

u8 res;      
if(USART1->SR&(1<<5))//接收到数据 

   res=USART1->DR; 
   if(InQueueInx>=UART_BUF_SIZE)   
   { 
      InQueueInx=0; 
   } 
   USART_RX_BUF[InQueueInx]=res; 
   InQueueInx++; 
    
        
}  
 #if 1 
if(USART1->SR&(1<<6))//发送区数据已经为空 

   USART1->SR&=~(3<<6);  
   if(TX_OutQueueInx==TX_InQueueInx) 
   { 

     USART1->SR&=~(3<<6);  
     return; 
   } 
   USART1->DR=USART_TX_BUF[TX_OutQueueInx]; 
   TX_OutQueueInx++; 
    if(TX_OutQueueInx>=UART_BUF_SIZE)  
     TX_OutQueueInx =0; 

   USART1->SR&=~(3<<6);  
}  
#endif   
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-19 08:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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