找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2935|回復(fù): 10
收起左側(cè)

串口計(jì)算器程序,電腦向單片機(jī)發(fā)送順序計(jì)算式1*2+3=不知道為什么在串口接收過來亂碼

[復(fù)制鏈接]
ID:435640 發(fā)表于 2023-6-20 18:32 | 顯示全部樓層 |閱讀模式
150黑幣
不知道程序那些地方有問題,不考慮算式優(yōu)先級,發(fā)送順式計(jì)算結(jié)果返回給串口,但是不知道為什么發(fā)送的是亂碼
單片機(jī)源程序如下:
#include<reg52.h>
#include<stdio.h>

unsigned char rec_data[32];
unsigned char op,flag, num[2],n=0;
unsigned int i,j,ansi=0,nm;
void delay_ms(int a)
{
        int b,d;
        for(b=a;b>0;b--)
        for(d=0;d<114;d--);
        
}
void chuankou_chushihua()//串口初始化程序
{
   TMOD|=0X20; //設(shè)置計(jì)數(shù)器1為工作方式 2
   SCON=0X50; //設(shè)置串行口為工作方式 1
   PCON=0X80; //波特率加倍
   TH1=0XFA; //計(jì)數(shù)器初始值設(shè)置9600baud
   TL1=0XFA;
   ES=1; //打開接收中斷
   EA=1; //打開總中斷
   TR1=1; //打開計(jì)數(shù)器
}

void uart() interrupt 4 //串口通信中斷函數(shù)
{
        
        RI = 0;                        //清除接收中斷標(biāo)志位
        rec_data[nm]=SBUF;        //存儲接收到的數(shù)據(jù)
        nm++;        
        flag=1;//設(shè)立標(biāo)識位
        }
void send_data( unsigned char jieguo)
{
        SBUF=jieguo;
        
        while(!TI);
                TI=0;
}
void panduan_jisuan()
{
        if('0'<=rec_data[0]&&rec_data[0]<='9')
    {// 將第一個(gè)數(shù)字存入num[0]
    num[0] = rec_data[0] - '0';

    // 掃描整個(gè)字符數(shù)組,從第二個(gè)字符開始逐一處理
    for (i = 1; i < nm; i++)
    {
        // 如果是運(yùn)算符,則將其存儲到op中,并將下一個(gè)數(shù)字存入num[1]
        if (rec_data[ i] == '+' || rec_data[ i] == '-' || rec_data[ i] == '*' ||rec_data[ i] == '/')
        {
            op = rec_data[ i];
            num[1] = rec_data[i + 1] - '0';
                        
            // 將指針移位至下一個(gè)數(shù)字
        }
        // 如果是等號,則運(yùn)算結(jié)果即為第一個(gè)數(shù)字
        else if (rec_data[ i] == '=')
        {
            ansi = num[0];
        }
        // 如果是數(shù)字,則根據(jù)之前的運(yùn)算符進(jìn)行運(yùn)算
        else if('0'<=rec_data[0]&&rec_data[0]<='9')
        {
            switch (op)
            {
                case '+':
                    num[0] = num[0] + (rec_data[ i] - '0');
                    break;
                case '-':
                    num[0] = num[0] - (rec_data[ i] - '0');
                    break;
                case '*':
                    num[0] = num[0] * (rec_data[ i] - '0');
                    break;
                case '/':
                    num[0] = num[0] / (rec_data[ i] - '0');
                    break;
            }
                         ansi=num[0];
        }
    }
        }
               
}
void send_int_to_serial_port(int c)
        {
    char buffer[16];

    // 使用 sprintf() 函數(shù)將整型變量轉(zhuǎn)換為字符串
    sprintf(buffer, "%d", c);

    // 將字符串逐個(gè)發(fā)送到串口
    for (i = 0; buffer[ i] != '\0'; i++)
                {
        send_data(buffer[ i]);
    }
        }
void main()
{         

        chuankou_chushihua( );        

        while(1)
        {
                if(flag==1)
                 {
                         panduan_jisuan();
                        
                        send_int_to_serial_port(ansi);
                 }   
    flag=0;                 
        }
}

回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2023-6-21 11:24 | 顯示全部樓層
1. flag不可以在每次進(jìn)中斷都賦值,應(yīng)改為串口超時(shí)后賦值
2. 如果TI不在中斷里清零,要在SBUF=。。。之前關(guān)中斷(ES=0;),TI清零后再開
回復(fù)

使用道具 舉報(bào)

ID:712097 發(fā)表于 2023-6-21 11:37 | 顯示全部樓層
串口通信亂碼通常都是波特率不匹配?聪掳l(fā)送固定內(nèi)容,每次接收到的亂碼是否相同。如果相同,則基本可以判定是波特率的問題。如果每次收到的都是隨機(jī)亂碼,則說明有干擾。
回復(fù)

使用道具 舉報(bào)

ID:435640 發(fā)表于 2023-6-21 11:44 | 顯示全部樓層
lkc8210 發(fā)表于 2023-6-21 11:24
1. flag不可以在每次進(jìn)中斷都賦值,應(yīng)改為串口超時(shí)后賦值
2. 如果TI不在中斷里清零,要在SBUF=。。。之前 ...

能否給改一下,串口第一次用
回復(fù)

使用道具 舉報(bào)

ID:1066657 發(fā)表于 2023-6-21 14:46 | 顯示全部樓層
這個(gè)首先要排除波特率誤差問題,其次才是報(bào)文等,因?yàn)榇谕ㄓ嵄容^簡單
回復(fù)

使用道具 舉報(bào)

ID:435640 發(fā)表于 2023-6-21 16:19 | 顯示全部樓層
oldhawk 發(fā)表于 2023-6-21 14:46
這個(gè)首先要排除波特率誤差問題,其次才是報(bào)文等,因?yàn)榇谕ㄓ嵄容^簡單

現(xiàn)在沒有亂碼只是計(jì)算結(jié)果為零
回復(fù)

使用道具 舉報(bào)

ID:1084404 發(fā)表于 2023-6-21 17:36 | 顯示全部樓層
系統(tǒng)亂碼:主要是Windows中顯示亂碼,比如菜單、桌面、啟動界面等,造成亂碼的主要原因是注冊表中有關(guān)字體部分出現(xiàn)錯(cuò)誤。
軟件亂碼:主要出現(xiàn)在各種軟件、游戲中,本該顯示中文的地方出現(xiàn)亂碼。這種亂碼的形成比較復(fù)雜,可能與系統(tǒng)亂碼的原因相同,也有可能是軟件中用到中文動態(tài)鏈接庫被其他原語言鏈接庫覆蓋所造成的。
文件亂碼:一般出現(xiàn)在文檔或者郵件中,這是比較常見的亂碼。出現(xiàn)這種情況往往是因?yàn)橄到y(tǒng)里沒有安裝可以打開該文件的軟件,或者該文件類型的打開方式錯(cuò)誤。
網(wǎng)頁亂碼:在瀏覽器打開的網(wǎng)頁中出現(xiàn)亂碼,一般來說,這是由于繁體中文大五碼(BIG5)與簡體中文(GB2312)不通用而造成的。
回復(fù)

使用道具 舉報(bào)

ID:1084901 發(fā)表于 2023-6-23 13:36 | 顯示全部樓層
想問一下你的亂碼是怎么解決的
回復(fù)

使用道具 舉報(bào)

ID:1086796 發(fā)表于 2023-7-2 15:56 | 顯示全部樓層
該單片機(jī)源程序存在幾個(gè)問題:  串口通信中斷函數(shù) uart() 中的 nm 變量沒有初始化,默認(rèn)為0,會導(dǎo)致接收到的數(shù)據(jù)存儲位置錯(cuò)誤。建議在主程序中的 chuankou_chushihua() 函數(shù)中將 nm 初始化為0。  panduan_jisuan() 函數(shù)中判斷數(shù)字的條件有誤,應(yīng)使用 rec_data[i] 判斷,而不是 rec_data[0]。正確的條件應(yīng)為 '0' <= rec_data[i] && rec_data[i] <= '9'。  在 panduan_jisuan() 函數(shù)中對運(yùn)算符進(jìn)行處理后,應(yīng)將指針移位至下一個(gè)字符,以避免重復(fù)處理已經(jīng)處理過的字符?梢栽 switch 語句執(zhí)行后,將 i 自增1,即 i++。  在 send_int_to_serial_port() 函數(shù)中,未定義變量 i,建議在函數(shù)內(nèi)部聲明 int i。  在 send_int_to_serial_port() 函數(shù)中,需要在發(fā)送每個(gè)字符之后等待發(fā)送完成,即等待 TI 標(biāo)志位被置位后再繼續(xù)發(fā)送下一個(gè)字符?梢栽 SBUF = jieguo; 后添加 while (!TI); 和 TI = 0;。
回復(fù)

使用道具 舉報(bào)

ID:821429 發(fā)表于 2023-7-3 15:12 | 顯示全部樓層
編程可以先畫個(gè)流程圖理清楚思路,整個(gè)程序思路有點(diǎn)亂,距離得到正確結(jié)果有點(diǎn)遠(yuǎn)……
回復(fù)

使用道具 舉報(bào)

ID:1040201 發(fā)表于 2023-7-4 09:28 | 顯示全部樓層
void delay_ms(int a)
{
        int b,d;
        for(b=a;b>0;b--)
        for(d=0;d<114;d--);    //d++?  d--沒有意義呀,重新算一下這個(gè)  或者用邏輯分析儀測試。
        
}         


進(jìn)了中斷  不清零,它出不去。      TI = 0;
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表