打印

很好,USART_SR的复位值为0x00C0

[复制链接]
2833|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
罗菜鸟|  楼主 | 2013-7-18 11:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
TXE和TC位复位值为1,这样的话,我用FIFO的形式,就可以不用担心如何去触发FIFO第一个字节的发送了。主函数内只往FIFO里面写入数据,写完后直接把USART_CTRL1的TXEIE值为1,就能进入TXE中断,中断里面读FIFO,然后写入USART_DR,FIFO空了的话就清TXEIE。
沙发
cdlxzlp520| | 2013-7-18 12:20 | 只看该作者
哈哈  不错 有代码看吗??

使用特权

评论回复
板凳
罗菜鸟|  楼主 | 2013-7-18 13:29 | 只看该作者
cdlxzlp520 发表于 2013-7-18 12:20
哈哈  不错 有代码看吗??
static __inline void _uart_isr(uint8_t port,struct _uart_fifo_t *pfifo,USART_TypeDef *uart)
{
        uint32_t iflag;
        uint32_t event = 0;
        uint8_t  read;
        iflag = (uart->CR1 & uart->SR);//(USART_FLAG_TXE|USART_FLAG_TC|USART_FLAG_RXNE|USART_FLAG_IDLE)
        //IDLE IRQ
        if(iflag & USART_FLAG_IDLE)
        {
                read = uart->DR;
                if(pfifo->rxCnt <= (pfifo->rxSize>>1)) //rx buffer is not full when rx idle happen
                {
                        event |=  UART_RX_DONE;
                }
        }
        //RX IRQ
        if(iflag & USART_FLAG_RXNE)
        {
                read = uart->DR;
                if(pfifo->rxCnt < pfifo->rxSize)
                {
                        pfifo->rxBuf[pfifo->rxPush] = read;
                        pfifo->rxPush += 1;
                        if(pfifo->rxPush >= pfifo->rxSize)
                        {
                                pfifo->rxPush = 0;
                        }
                        pfifo->rxCnt += 1;
                        if(pfifo->rxCnt == pfifo->rxSize)  //rx buffer is full
                        {
                                event |= UART_RX_FULL;
                        }
                        else if(pfifo->rxCnt > (pfifo->rxSize>>1))//rx byte is more than half of rx buffer  
                        {
                                event |= UART_RX_HALF;
                        }
                }
        }
        //TXE IRQ
        if(iflag & USART_FLAG_TXE)
        {
                uart->CR1 &= (uint16_t)~0x0080; //off TX
                if(pfifo->txCnt)
                {
                        uart->DR   = pfifo->txBuf[pfifo->txPop];
                        uart->CR1 |= (uint16_t)0x0080;
                        pfifo->txPop += 1;
                        if(pfifo->txPop >= pfifo->txSize)
                        {
                                pfifo->txPop = 0;
                        }
                        pfifo->txCnt -= 1;
                        if(pfifo->txCnt == 0)
                        {
                                event |=  UART_TX_DONE;
                        }
                }
        }
        //run isr function
        if((pfifo->isr) && (event))
        {
                event |= (uint8_t)port<<8 ;
                pfifo->isr(event,pfifo->msg);
        }
}

使用特权

评论回复
地板
jack888518| | 2013-7-18 14:12 | 只看该作者
这是不是传说中ST的USART的一个会导致程序“奇怪”的地方?
看样子GD的芯片没有这个问题...

使用特权

评论回复
5
cool_coder| | 2013-7-18 17:03 | 只看该作者
对于没有DMA的芯片这样很好;不过,GD32是带DMA的,有更好的选择,至少发送数据时是这样。

使用特权

评论回复
6
罗菜鸟|  楼主 | 2013-7-19 15:09 | 只看该作者
jack888518 发表于 2013-7-18 14:12
这是不是传说中ST的USART的一个会导致程序“奇怪”的地方?
看样子GD的芯片没有这个问题... ...

不是bug,而是处理技巧。

使用特权

评论回复
7
罗菜鸟|  楼主 | 2013-7-19 15:10 | 只看该作者
cool_coder 发表于 2013-7-18 17:03
对于没有DMA的芯片这样很好;不过,GD32是带DMA的,有更好的选择,至少发送数据时是这样。 ...

收数据呢?

使用特权

评论回复
8
cool_coder| | 2013-7-19 16:23 | 只看该作者
罗菜鸟 发表于 2013-7-19 15:10
收数据呢?

收数据的时候要用DMA,定长的还好说,要是变长数据的话……,反正我觉得不够方便。

使用特权

评论回复
9
罗菜鸟|  楼主 | 2013-7-19 22:34 | 只看该作者
cool_coder 发表于 2013-7-19 16:23
收数据的时候要用DMA,定长的还好说,要是变长数据的话……,反正我觉得不够方便。 ...

DMA不是有个寄存器可以查询当前收了多少数据么?
另外,UART有个IDLE中断。

使用特权

评论回复
10
shenpingbing| | 2013-8-29 22:39 | 只看该作者
不是很明白啊

使用特权

评论回复
11
make8419247| | 2013-11-21 08:10 | 只看该作者
顶一个!!!

使用特权

评论回复
12
喵小棋| | 2013-11-24 23:56 | 只看该作者
不明觉厉

使用特权

评论回复
13
heshenggui| | 2013-11-25 19:56 | 只看该作者
不是很明白

使用特权

评论回复
14
fangxingyi| | 2013-11-28 20:44 | 只看该作者
学一下

使用特权

评论回复
15
huangjia22| | 2013-12-22 09:59 | 只看该作者
学习一下

使用特权

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

本版积分规则

132

主题

522

帖子

8

粉丝