打印
[STM32F1]

STM32 用 串口 2 发生错误!内有代码

[复制链接]
1029|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
情场探花|  楼主 | 2017-11-5 15:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 情场探花 于 2017-11-5 15:39 编辑

先说说我的环境:
KEIL MDK4.6, STM32F103C8T6,ST LINK
我想用 USART2 (PA2 和 PA3 )收发数据。目前调试阶段,把 PA2 和 PA3 短接。
症状:总是会多收一个  0x00,检查后发现接收缓冲区的指针 in, 就是 g_RxBuf.in 总是多加。按道理我发一个字节,它应该加1,实际增加了2,就是说收到了 2 个字节。由于是在办公室里,而且 TX 和 RX 都是短接的,所以也不像是是干扰。推测是初始化设置没弄好,特此请大侠指点一下。函数 SendChar() 是发送一个字节,我每次只发一个字节 0x55,然后就是接收了。结果收到的是 0x55 0x00
函数 GetKey() 是接收一个字节,如果缓冲区空则返回 -1.

#define CLOCK 72/8 //时钟频率72M

struct buf_st {
  unsigned int in;                        /* Next In Index                    */
  unsigned int out;                       /* Next Out Index                   */
  char buf [RBUF_SIZE];                   /* Buffer                           */
};

static struct buf_st g_RxBuf = { 0, 0, };
#define SIO_RBUFLEN ((unsigned short)(g_RxBuf.in - g_RxBuf.out))

static struct buf_st g_TxBuf = { 0, 0, };
#define SIO_TBUFLEN ((unsigned short)(g_TxBuf.in - g_TxBuf.out))

static unsigned int g_bTxRestart = 1;       /* NZ if TX restart is required     */

void USART2_Init(void)
{
                int i;
                RCC->APB2ENR |=  (   1UL <<  0);        /* enable clock Alternate Function  */
                AFIO->MAPR   &= ~(   1UL <<  3);        /* clear USART2 remap               */
                RCC->APB2ENR |=  (   1UL <<  2);        /* enable GPIOA clock               */
                GPIOA->CRL &= 0xffff00ff;
                GPIOA->CRL |= 0xb00;        //PA2: output push-pull, Max. 50M speed
                GPIOA->CRL |= 0x4000;        //PA3: input floating
                RCC->APB1ENR |= 0x020000;  //¼´ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
                USART2->BRR = 0x1d4c;
                 USART2->CR1   = ((   1UL <<  2) |       /* enable RX                        */
                                                (   1UL <<  3) |       /* enable TX                        */
                                                (   1UL <<  5) |       /* enable RXNE Interrupt            */
                                                (   1UL <<  7) |       /* enable TXE Interrupt             */
                                                (   0UL << 12) );      /* 1 start bit, 8 data bits         */
                USART2->CR2   = 0x0000;                 /* 1 stop bit                       */
                USART2->CR3   = 0x0000;                 /* no flow control                  */
                for (i = 0; i < 0x1000; i++) __NOP();   /* avoid unwanted output            */

                NVIC_EnableIRQ(USART2_IRQn);
                USART2->CR1  |= 0x2000;      /* enable USART                     */
}


void USART2_IRQHandler (void) {
            volatile unsigned int IIR;
             struct buf_st *p;
            IIR = USART2->SR;
            if (IIR & USART_SR_RXNE) {            /* read interrupt                   */
                           USART2->SR &= ~USART_SR_RXNE;              /* clear interrupt                  */
                            p = &g_RxBuf;
                            if (((p->in - p->out) & ~(RBUF_SIZE-1)) == 0) {
                                        p->buf [p->in & (RBUF_SIZE-1)] = (USART2->DR & 0x1FF);
                                        p->in++;
                            }
             }

             if (IIR & USART_SR_TXE) {
                         USART2->SR &= ~USART_SR_TXE;              /* clear interrupt                    */
                        p = &g_TxBuf;
                        if (p->in != p->out) {
                                   USART2->DR = (p->buf [p->out & (TBUF_SIZE-1)] & 0x1FF);
                                   p->out++;
                                   g_bTxRestart = 0;
                         }
                       else {
                                    g_bTxRestart = 1;
                                    USART2->CR1 &= ~USART_SR_TXE;     /* disable TX IRQ if nothing to send  */
                        }
             }
}

void buffer_Init (void) {
            g_TxBuf.in = 0;                            /* Clear com buffer indexes           */
             g_TxBuf.out = 0;
            g_bTxRestart = 1;
            g_RxBuf.in = 0;
            g_RxBuf.out = 0;
}

int SendChar (int c) {
        int iii;
       struct buf_st *p = &g_TxBuf;
         if (SIO_TBUFLEN >= TBUF_SIZE)           /* If the buffer is full              */
                         return (-1);                          /* return an error value              */
        p->buf [p->in & (TBUF_SIZE - 1)] = c;   /* Add data to the transmit buffer.   */
        p->in++;
        if (g_bTxRestart) {                       /* If TX interrupt is disabled        */
                    g_bTxRestart = 0;                       /*     enable it                      */
                    USART2->CR1 |= USART_SR_TXE;          /* enable TX interrupt                */
          }
         return (0);
}

char GetKey (void)
{        int iii;
      struct buf_st *p = &g_RxBuf;

       if (SIO_RBUFLEN == 0)
                   return (0xff);
       return (p->buf [(p->out++) & (RBUF_SIZE - 1)]);
}



沙发
情场探花|  楼主 | 2017-11-12 10:41 | 只看该作者
问题解决了。谁要分啊?

使用特权

评论回复
板凳
一路向北lm| | 2017-11-12 12:26 | 只看该作者
用串口1试下,检查下串口的配置。

使用特权

评论回复
地板
caijie001| | 2017-11-12 12:50 | 只看该作者
情场探花 发表于 2017-11-12 10:41
问题解决了。谁要分啊?

可以分享出来是怎么回事的,大家也能讨论下

使用特权

评论回复
5
情场探花|  楼主 | 2017-11-12 21:26 | 只看该作者
caijie001 发表于 2017-11-12 12:50
可以分享出来是怎么回事的,大家也能讨论下

其实没错误,是我自己昏头了

使用特权

评论回复
6
caijie001| | 2017-11-12 22:07 | 只看该作者
情场探花 发表于 2017-11-12 21:26
其实没错误,是我自己昏头了

哈哈哈。没事,我也是经常这样

使用特权

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

本版积分规则

446

主题

1203

帖子

6

粉丝