久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1610|回復: 3
打印 上一主題 下一主題
收起左側

m8單片機串口通訊程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:1104531 發表于 2024-1-11 21:08 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
個人認為,AVR系列的串口使用還是比較容易出錯,如果采用傳統的查詢方式太耗系統時間,而且現在關于AVR的教材大多給你的是查詢發送方式,中斷接收方式。
本例子是采用中斷接收,中斷發送方式。希望對大家有所幫助。

//ICC-AVR
// Target : M8
// Crystal: 4.0000Mhz

#include <iom8v.h>
#include <macros.h>

#define DISABLE_UARTTX()        UCSRB&=~BIT(TXCIE)
#define ABLE_UARTTX()                UCSRA|=BIT(TXC);UCSRB|=BIT(TXCIE)

unsigned char ucRecv;
unsigned char ucRecvOk;

unsigned char ucSendData[8]="Recv OK!";
unsigned char ucComSendCnt,ucComSendPtr;


void InitPort(void)
{
         PORTB = 0xFF;
         DDRB  = 0x00;
         PORTC = 0x7F; //m103 output only
         DDRC  = 0x00;
         PORTD = 0xFE;
         DDRD  = 0x02;
}

//UART0 initialize
// desired baud rate: 2400
// actual: baud rate:2404 (0.2%)
void InitUart0(void)
{
         UCSRB = 0x00; //disable while setting baud rate
         UCSRA = 0x00;
         UCSRC = BIT(URSEL) | 0x06;
         UBRRL = 0x67; //set baud rate lo
         UBRRH = 0x00; //set baud rate hi
         UCSRB = 0x98;
}

#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
        unsigned char ucTmp;
//uart has received a character in UDR
        ucTmp=UDR;
        if (ucTmp=='A')
        {
                ucRecv=ucTmp;
                ucRecvOk=0x01;        
        }
}


#pragma interrupt_handler uart0_tx_isr:iv_USART0_TXC
void uart0_tx_isr(void)
{
//character has been transmitted
         if (ucComSendCnt!=0)
         {
                 ucComSendPtr+=1;
                 UDR=ucSendData[ucComSendPtr];
                ucComSendCnt-=1;
        }else
        {        
                //PORTB&=~BIT(PB_COM_LED);                                        //串口指示燈滅
                DISABLE_UARTTX();
                //PORTB^=BIT(PB_COM_LED);                                        //串口指示燈滅
        }
}



//call this routine to initialize all peripherals
void InitMcu(void)
{
//stop errant interrupts until set up
         CLI();                         //disable all interrupts
         InitPort();
         InitUart0();

         MCUCR = 0x00;
         GICR  = 0x00;
         TIMSK = 0x00;         //timer interrupt sources
         SEI();                         //re-enable interrupts
                                         //all peripherals are now initialized
}



void main(void)
{
        unsigned char i;
        InitMcu();
        while(1)
        {
                if (ucRecvOk==0x01)
                {
                        CLI();
                        ucRecvOk=0;
                        SEI();
                        
                        ucComSendCnt=7;
                        ucComSendPtr=0;
                        ABLE_UARTTX();
                        UDR=ucSendData[0];
                }        
        }
}

m8 串口通訊.zip

44.24 KB, 下載次數: 4, 下載積分: 黑幣 -5

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:229502 發表于 2024-2-11 21:18 | 只看該作者
樓主能否有個注解,對初學者更友好
回復

使用道具 舉報

板凳
ID:1126818 發表于 2024-8-30 21:59 來自手機 | 只看該作者
新手上路,多多指教。有沒有發送十六進的程序?
回復

使用道具 舉報

地板
ID:342822 發表于 2024-9-1 19:17 | 只看該作者
用文心一言給他來個中文注釋:
#include <iom8v.h> // 包含特定于ATmega8V或其他兼容AVR型號的頭文件,提供寄存器定義等  
#include <macros.h> // 包含宏定義,可能用于簡化位操作或寄存器訪問  
  
// 定義宏來啟用和禁用UART發送完成中斷  
#define DISABLE_UARTTX()        UCSRB &= ~BIT(TXCIE) // 清除UCSRB寄存器中的TXCIE位,禁用UART發送完成中斷  
#define ABLE_UARTTX()           UCSRA |= BIT(TXC); UCSRB |= BIT(TXCIE) // 設置UCSRA的TXC位和UCSRB的TXCIE位,準備發送并啟用中斷  
  
// 全局變量,用于接收和發送數據  
unsigned char ucRecv; // 接收到的字符  
unsigned char ucRecvOk; // 接收標志,接收到特定字符時置位  
  
unsigned char ucSendData[8]="Recv OK!"; // 要發送的數據  
unsigned char ucComSendCnt, ucComSendPtr; // 發送計數器和指針  
  
// 初始化GPIO端口  
void InitPort(void)  
{  
    PORTB = 0xFF; // 設置PORTB的所有位為高電平(具體功能取決于硬件連接)  
    DDRB  = 0x00; // 設置PORTB為輸入模式  
    PORTC = 0x7F; // 設置PORTC的部分位為高電平(假設m103為輸出)  
    DDRC  = 0x00; // 設置PORTC為輸入模式  
    PORTD = 0xFE; // 設置PORTD的特定位為高電平  
    DDRD  = 0x02; // 設置PORTD的特定位為輸出模式  
}  
  
// 初始化UART0  
// 設定波特率為2400,但實際可能略有偏差(如2404)  
void InitUart0(void)  
{  
    UCSRB = 0x00; // 在設置波特率時禁用UART  
    UCSRA = 0x00; // 清除UCSRA寄存器  
    UCSRC = BIT(URSEL) | 0x06; // 設置UCSRC寄存器以啟用異步USART模式,并設置字符大小為8位  
    UBRRL = 0x67; // 設置波特率低位  
    UBRRH = 0x00; // 設置波特率高位  
    UCSRB = 0x98; // 啟用接收器和發送器,設置接收中斷使能  
}  
  
// UART接收中斷服務例程  
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC  
void uart0_rx_isr(void)  
{  
    unsigned char ucTmp;  
    // UART已接收到一個字符  
    ucTmp = UDR; // 從UDR寄存器讀取接收到的字符  
    if (ucTmp == 'A') // 如果接收到的字符是'A'  
    {  
        ucRecv = ucTmp; // 保存接收到的字符  
        ucRecvOk = 0x01; // 設置接收標志  
    }  
}  
  
// UART發送中斷服務例程  
#pragma interrupt_handler uart0_tx_isr:iv_USART0_TXC  
void uart0_tx_isr(void)  
{  
    // 字符已發送  
    if (ucComSendCnt != 0) // 如果還有字符需要發送  
    {  
        ucComSendPtr += 1; // 發送指針遞增  
        UDR = ucSendData[ucComSendPtr]; // 發送下一個字符  
        ucComSendCnt -= 1; // 發送計數器遞減  
    }  
    else  
    {  
        // 發送完成,禁用UART發送中斷  
        DISABLE_UARTTX();  
        // 注釋掉的代碼可能用于控制串口指示燈  
    }  
}  
  
// 初始化微控制器所有外設  
void InitMcu(void)  
{  
    // 在設置完成前停止錯誤中斷  
    CLI(); // 禁用所有中斷  
    InitPort(); // 初始化GPIO端口  
    InitUart0(); // 初始化UART0  
  
    MCUCR = 0x00; // 清除MCU控制寄存器  
    GICR  = 0x00; // 清除全局中斷控制寄存器(注意:某些AVR型號可能沒有GICR)  
    TIMSK = 0x00; // 清除定時器中斷源掩碼寄存器(此處用于確保沒有定時器中斷)  
    SEI(); // 重新啟用中斷  
    // 所有外設現已初始化完成  
}  
  
// 主函數  
void main(void)  
{  
    unsigned char i; // 未使用的變量,可能用于調試或保留  
    InitMcu(); // 初始化微控制器  
    while(1) // 無限循環  
    {  
        if (ucRecvOk == 0x01) // 如果接收到特定字符  
        {  
            CLI(); // 禁用中斷  
            ucRecvOk = 0; // 清除接收標志  
            SEI(); // 重新啟用中斷  
  
            ucComSendCnt = 7; // 設置發送計數器  
            ucComSendPtr = 0; // 重置發送指針  
            ABLE_UARTTX(); // 準備發送并啟用發送中斷  
            UDR = ucSendData[0]; // 發送第一個字符以啟動發送過程  
        }  
    }  
}
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产区一区二区三区 | 爱爱视频日本 | 国产精品久久a | 亚洲一区二区三区四区五区中文 | 国产精品免费一区二区 | 视频在线亚洲 | 色婷婷综合久久久中字幕精品久久 | 精品96久久久久久中文字幕无 | 一区| 国产一区二区在线视频 | 成人av在线大片 | 一级毛片在线播放 | 亚洲人va欧美va人人爽 | 一区二区三区中文字幕 | 亚洲性爰 | av香蕉| 中文成人在线 | 福利精品 | 国产特级毛片 | 亚洲精品福利在线 | 欧美一区二区免费 | 日韩欧美三级电影 | 国产激情一区二区三区 | 亚洲少妇综合网 | 久久高清| 午夜免费福利电影 | 国产乱肥老妇国产一区二 | 337p日本欧洲亚洲大胆 | 91视频网址 | 一级看片 | 午夜欧美日韩 | 国产精品一区在线 | 嫩草网 | 国产一区免费视频 | 久久精品国产免费一区二区三区 | 亚洲国产精品va在线看黑人 | 国产高清在线视频 | 日本福利一区 | 一区欧美 | 美国黄色毛片 | 久久国产日本 |