打印

STM32 串口收发问题

[复制链接]
6705|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhpg009|  楼主 | 2012-3-10 21:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/******************************************************************/
/****************************  STM32开发  *************************/
/****************************  串口实验          *************************/
/******************************************************************/
#include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"               
#include "delay.h"       
#include "led.h"
#include "key.h"                  

int main(void)
{                       
        Stm32_Clock_Init(9);     //系统时钟设置
        delay_init(72);                 //延时初始化
        usart_init(72,115200);         //串口初始化为115200
        LED_Init();                               //初始化与LED连接的硬件接口
        while(1)
        {
                GetInputString(USART_RX_BUF);
                printf("\r\n您输入的信息为:[%s]\n\r",USART_RX_BUF);
        }
}


/**
  * @brief  Get Input string from the HyperTerminal
  *         从超级终端输入字符串
  * @param  buffP: The input string
  * @retval None
  **/
void GetInputString(u8 *buffp)
{
        u32 byte_mark=0;                 //定义一个标记第几个字符的变量byte_mark
        u8 c=0;
        do
        {
                c=GetKey();
                if(c=='\r')                         //"Enter"键功能,回车换行
                        break;
                if(c=='\b')                         //“Backspace”键功能
                {
                        if(byte_mark>0)
                        {
                                printf("\b \b");             //第一步,将光标移到前一列。第二步,用空格符覆盖当前列
                                byte_mark--;                //第三步,再将光标移到前一列。
                        }
                        continue;
                }
                if(byte_mark>=(CMD_STRING_SIZE))
                {
                        printf("Command String size overflow\r\n");
                        byte_mark=0;
                        continue;
                }
                if(c>=0X20&&c<=0X7E)                  
                {
                        buffp[byte_mark++]=c;
                      SerialPutChar(c);                     //将字符串一个一个输出
                }

        }
        while(1);
        printf("\n\r");
        buffp[byte_mark]='\0';
}

/**
  * @brief  Wait until Get a key from the HyperTerminal
  *         从超级终端获取字符串
  * @param  None
  * @retval The Key Pressed
  **/
u8 GetKey(void)
{
        u8 key=0;
        while (1)
        {
                if(SerialKeyPressed((u8*)&key))
                        break;
        }
        return key;
}

/**
  * @brief  Test to see if a key has been pressed on the HyperTerminal
  *         检测是否有字符 从超级终端 键入
  * @param  key: The key pressed
  * @retval 1: Correct
  *         0: Error
  **/
u32 SerialKeyPressed(u8 *key)
{
  /* 当接收移位寄存器中的数据被转移到接收数据寄存器(RDR)里面时,
   * USART1->SR里面的RXNE=1(表示收到数据),即USART1->SR&0X20=1 。
   */
        if ((USART1->SR&0X20)!=0)  
        {                                                                         
                *key=(u8)USART1->DR&0xFF;                 
                return 1;          //表示收到数据,可以读出
        }
        else
        {
                return 0;          //表示没有收到数据
        }
}

/**
  * @brief  Print a character on the HyperTerminal
  * @param  c: The character to be printed
  * @retval None
  * 如果数据发送完成,USART1->SR的TC位便会置1,即TC=1。
  * 然后退出循环。
  **/
void SerialPutChar(u8 c)
{
        USART1->DR=(c&(u16)0x01FF);                //发送数据c
        while((USART1->SR&0X40)==0);         //等待发送结束,TC=1时,表示数据发送完成       
}


/********************************STM32开发************************************/
/*******************************串口1初始化***********************************/

#include "sys.h"
#include "usart.h"                            

/****************************************************************************/
/*************       支持适应不同频率下的串口波特率设置           ***********/
/*************             加入了对printf的支持                   ***********/
/*************            增加了串口接收命令功能                  ***********/
/*************加入以下代码,支持printf函数,而不需要选择use MicroLIB***********/          
/****************************************************************************/

#if 1
#pragma import(__use_no_semihosting)  
           
//标准库需要的支持函数                 
struct __FILE
{
        int handle;
        /* Whatever you require here. If the only file you are using is */
        /* standard output using printf() for debugging, no file handling */
        /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;   
     
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
//重定义fputc函数

int fputc(int ch, FILE *f)
{      
        USART1->DR = (u8) ch;      
        while((USART1->SR&0X40)==0);  //循环发送,直到发送完毕   
        return ch;
}
#endif
//end

#ifdef EN_USART1_RX               //如果使能了接收

//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误          
u8 USART_RX_BUF[CMD_STRING_SIZE]; //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0;                //接收状态标记          
  
void USART1_IRQHandler(void)
{
        u8 res;            
        if(USART1->SR&(1<<5))         //接收到数据
        {         
                res=USART1->DR;
                if((USART_RX_STA&0x80)==0)//接收未完成
                {
                        if(USART_RX_STA&0x40) //接收到了0x0d
                        {
                                if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
                                else USART_RX_STA|=0x80;        //接收完成了
                        }
                        else                 //还没收到0X0D
                        {       
                                if(res==0x0d)USART_RX_STA|=0x40;
                                else
                                {
                                        USART_RX_BUF[USART_RX_STA&0X3F]=res;
                                        USART_RX_STA++;
                                        if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收          
                                }                 
                        }
                }                                                                                                
        }                                                                                           
}
#endif       
                                                                         
//初始化IO 串口1
//pclk2:PCLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void usart_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=0X444444B4;                     //IO状态设置
                  
        RCC->APB2RSTR|=1<<14;                      //复位串口1
        RCC->APB2RSTR&=~(1<<14);                   //停止复位
                             
        //波特率设置
        USART1->BRR=mantissa;                      // 波特率设置         
        USART1->CR1|=0X200C;                       //1位停止,无校验位.
    #ifdef EN_USART1_RX                                   //如果使能了接收

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

/******************************************************************/
/******************************************************************/
#ifndef __USART_H
#define __USART_H
#include <stm32f10x_lib.h>
#include "stdio.h"         
//STM32开发板
//串口1初始化
                          
#define CMD_STRING_SIZE  64          
       
extern u8 USART_RX_BUF[CMD_STRING_SIZE];     //接收缓冲,最大63个字节.末字节为换行符
extern u8 USART_RX_STA;                      //接收状态标记       

#define EN_USART1_RX     //使能串口1接收


void usart_init(u32 pclk2,u32 bound);                                                                 
void GetInputString(u8 *buffp);
void SerialPutChar(u8 c);
u32 SerialKeyPressed(u8 *key);
u8 GetKey(void);

#endif          

问题是:输入字符串时很慢,有时候字符串输入不了;按回车输出的时候 Enter键要按很多次才能显示在超级终端上。
比如,我连续输入10次j ,结果终端上只显示2个。
不知道是哪里的问题,跪求各位的帮助!
沙发
zhpg009|  楼主 | 2012-3-10 21:32 | 只看该作者
jj

您输入的信息为:[jj]


您输入的信息为:[]

使用特权

评论回复
板凳
zhpg009|  楼主 | 2012-3-10 21:32 | 只看该作者
上面这个就是我说的问题。:Q

使用特权

评论回复
地板
zhpg009|  楼主 | 2012-3-13 12:41 | 只看该作者
哎,到今天都没人看,估计我写的太烂了!

使用特权

评论回复
5
香水城| | 2012-3-13 13:58 | 只看该作者
哎,到今天都没人看,估计我写的太烂了!
zhpg009 发表于 2012-3-13 12:41


一般上,在论坛上是没有人有心思去看大段程序的。

使用特权

评论回复
6
yqfyqf1| | 2012-10-9 20:04 | 只看该作者
jj
您输入的信息为:[jj]
您输入的信息为:[]

没有JJ

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:进取

16

主题

139

帖子

0

粉丝