首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PIC18上写UART

在PIC18上写UART
EN

Stack Overflow用户
提问于 2016-08-02 07:56:40
回答 3查看 1.3K关注 0票数 3

我需要帮助uart通讯,我正试图实现我的Proteus模拟。我使用一个PIC18f4520,我想在虚拟终端上显示由微控制器计算出来的值。

这是我在Proteus上设计的一个快照

现在,我的UART代码是这样的:

代码语言:javascript
复制
#define _XTAL_FREQ  20000000
#define _BAUDRATE   9600

void Configuration_ISR(void) {
    IPR1bits.TMR1IP = 1;        // TMR1 Overflow Interrupt Priority - High
    PIE1bits.TMR1IE = 1;        // TMR1 Overflow Interrupt Enable
    PIR1bits.TMR1IF = 0;        // TMR1 Overflow Interrupt Flag
                            //   0 = TMR1 register did not overflow
                            //   1 = TMR1 register overflowed (must be cleared in software)
    RCONbits.IPEN   = 1;        // Interrupt Priority High level
    INTCONbits.PEIE = 1;        // Enables all low-priority peripheral interrupts
    //INTCONbits.GIE  = 1;          // Enables all high-priority interrupts
}

void Configuration_UART(void) {
    TRISCbits.TRISC6 = 0;
    TRISCbits.TRISC7 = 1;

    SPBRG = ((_XTAL_FREQ/16)/_BAUDRATE)-1;

    //RCSTA REG
    RCSTAbits.SPEN = 1;     // enable serial port pins    
    RCSTAbits.RX9 = 0;

    //TXSTA REG
    TXSTAbits.BRGH = 1;     // fast baudrate
    TXSTAbits.SYNC = 0;     // asynchronous
    TXSTAbits.TX9 = 0;      // 8-bit transmission
    TXSTAbits.TXEN = 1;     // enble transmitter
}

void WriteByte_UART(unsigned char ch) {
    while(!PIR1bits.TXIF);  // Wait for TXIF flag Set which indicates
                            // TXREG register is empty
    TXREG = ch;             // Transmitt data to UART
}

void WriteString_UART(char *data) { 
       while(*data){ 
          WriteByte_UART(*data++); 
       }
}

unsigned char ReceiveByte_UART(void) {
    if(RCSTAbits.OERR) {
        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
    }
    while(!PIR1bits.RCIF); //Wait for a byte
    return RCREG;
}

在主回路中:

代码语言:javascript
复制
while(1) {
    WriteByte_UART('a'); // This works. I can see the As in the terminal
    WriteString_UART("Hello World !"); //Nothing displayed :(
}//end while(1)

我为WriteString_UART尝试过不同的解决方案,但到目前为止都没有奏效。

我不想使用printf,因为它通过添加延迟来影响我正在用PIC做的其他操作。所以我真的很想让它与WriteString_UART一起工作。最后,我希望在终端上有“错误率是:值%”之类的东西。

谢谢你的帮助,如果有什么不清楚的话请告诉我。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-08-03 18:47:38

在您的WriteByte_UART()函数中,尝试轮询TRMT位。特别是,改变:

代码语言:javascript
复制
while(!PIR1bits.TXIF);

代码语言:javascript
复制
while(!TXSTA1bits.TRMT);

我不知道这是否是您的特定问题,但是由于TXIF在加载TXREG时没有立即被清除,存在一个竞赛条件。另一种选择是尝试:

代码语言:javascript
复制
...
Nop();
while(!PIR1bits.TXIF);
...

基于注释的编辑

这个问题是由于PIC18使用了基于数据内存和程序内存的两种不同的指针类型。尝试将声明更改为void WriteString_UART(const rom char * data),看看会发生什么。您还需要将WriteByte_UART()声明更改为void WriteByte_UART(const unsigned char ch)

票数 2
EN

Stack Overflow用户

发布于 2016-08-03 16:09:48

  1. 在行TXREG = ch;之后添加几毫秒的延迟
  2. 验证WriteString_UART的指针*数据(char *data)是否确实指向 弦乐“你好世界!”
票数 1
EN

Stack Overflow用户

发布于 2016-08-25 16:02:08

你似乎找到了一个解决方案,但它一开始不起作用的原因还不清楚。你在使用什么编译器?

我学到了C18和XC8在内存空间方面的不同用法。使用这两个编译器,一个声明为char string[]="Hello!"的字符串将存储在ROM (程序内存)中。它们在函数使用字符串的方式上有所不同。

C18字符串函数将具有访问RAM或ROM中字符串的变体(例如,strcpypgm2ramstrcpyram2pgm等)。另一方面,XC8为您执行任务,您不需要使用特定的函数来选择要访问的内存。

如果您正在使用C18,我强烈建议您切换到XC8,这是最近才使用的,而且使用起来更容易。如果您仍然希望使用C18或另一个需要处理程序/数据内存空间的编译器,那么下面是您可能要尝试的两种解决方案。C18数据表表示,putsUSART从数据内存中打印一个字符串到USART。函数putrsUSART将从程序内存中打印一个字符串。因此,您可以简单地使用putrsUSART打印字符串。

您还可以尝试以下方法,这包括将字符串从程序内存复制到数据内存(如果应用程序内存紧张,则可能会浪费内存):

代码语言:javascript
复制
char pgmstring[] = "Hello";
char datstring[16];
strcpypgm2ram(datstring, pgmstring);
putsUSART(datstring);

在本例中,指针pgmstringdatstring将存储在数据内存中。字符串"Hello"将存储在程序内存中。因此,即使指针pgmstring本身在数据内存中,它也最初指向一个内存地址("Hello"地址)。指向数据内存中相同字符串的唯一方法是在数据内存中创建该字符串的副本。这是因为接受存储在数据内存(如putsUSART)中的字符串的函数不能直接与存储在程序内存中的字符串一起使用。

我希望这能帮助你更好地理解如何使用哈佛微处理器,在那里程序和数据记忆是分开的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38714798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档