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

標題: stc15f2k60s2單片機利用串口傳輸字模存儲到eeprom并進行點陣顯示 [打印本頁]

作者: 小小白玩mcu    時間: 2024-11-1 13:57
標題: stc15f2k60s2單片機利用串口傳輸字模存儲到eeprom并進行點陣顯示
想做一個電子名牌,上位機端大致已經弄好,現在單片機端程序還有問題。程序首先讀取eeprom的數據存儲到buffer數組中,主函數初始化串口,根據標志位決定是否擦除扇區,并將通過串口接受的數據存入eeprom,實質就是看串口有無數據進來,沒有就顯示原本存儲的數據,標志位是一個全局變量,由中斷程序控制值。代碼我貼在下面,目前就是使用isp打開串口后,顯示會短暫消失一下,進入了while(1)循環,發送數據不起作用,有沒有大神解答一下問題。
單片機源程序如下:
#include <stc15f2k60s2.h>
#include "eeprom.h"
#define uchar unsigned char
#define uint unsigned int

/* 點陣顯示宏定義 */
sbit KEY = P3 ^ 2;
sbit T_STR = P3 ^ 7;    // 鎖存引腳
sbit T_IO  = P1 ^ 4;    // 數據引腳
sbit T_CLK = P3 ^ 6;    // 時鐘引腳
sbit T_OE  = P3 ^ 5;

uchar row = 0, col;
uchar xdata receivedData[16][8];
uchar xdata buffer[256];
uint flag = 0;
uint count = 0;
uint eepromAddress = 0x0000;

void UartInit(void) {
        PCON &= 0x7F; // 波特率不倍速
        SCON = 0x50; // 8位數據,可變波特率
        AUXR |= 0x40; // 定時器1時鐘為Fosc
        AUXR &= 0xFE; // 串口1選擇定時器1為波特率發生器
        TMOD &= 0x0F; // 清除定時器1模式位
        TMOD |= 0x20; // 設定定時器1為8位自動重裝方式
        TL1 = 0xDC; // 設定初值
        TH1 = 0xDC; // 設定定時器重裝初值
        ET1 = 0; // 禁止定時器1中斷
        TR1 = 1; // 啟動定時器1
        ES = 1; // 開啟串口中斷允許
        EA = 1; // 開啟全局中斷允許
}

unsigned char AsciiToHex(unsigned char ascii) {
        if (ascii >= '0' && ascii <= '9') {
                return ascii - '0';   // 將字符 '0'-'9' 轉換為 0x0-0x9
        } else if (ascii >= 'A' && ascii <= 'F') {
                return ascii - 'A' + 0xA;   // 將字符 'A'-'F' 轉換為 0xA-0xF
        } else {
                return 0x00;  // 如果不在范圍內,返回默認值 0x00
        }
}

void ReadFromEeprom(uint address) {
        uint i, j;
        for (i = 0; i < 16; i++) { // 遍歷16行
                for (j = 0; j < 8; j++) { // 每行8個字節
                        unsigned char highByteAscii = IapReadByte(address);     // 讀取高位 ASCII
                        unsigned char lowByteAscii = IapReadByte(address + 1);  // 讀取低位 ASCII
                        // 轉換 ASCII 值為十六進制數字
                        unsigned char highByte = AsciiToHex(highByteAscii);
                        unsigned char lowByte = AsciiToHex(lowByteAscii);
                        // 合并高、低位為一個8位的十六進制數
                        receivedData[ i][j] = (highByte << 4) | (lowByte & 0x0F);
                        address += 2;  // 每次讀取后地址增加2,以讀取下一個字節對
                }
        }
}

void WriteToEeprom(uint address, uchar data1) {
        IapProgramByte(address, data1); // 使用定義好的函數寫入EEPROM
}

void Delay(unsigned int t) {
        while (--t);
}

void InputByte(unsigned char dat) {
        unsigned char i;
        for (i = 0; i < 8; i++) {
                T_IO = !(dat & 0x01);
                dat >>= 1;
                T_CLK = 0;
                T_CLK = 1;
        }
}

/*void SendString(uchar *str) {
        while (*str) {
                SBUF = *str++;
                while (!TI);
                TI = 0;
        }
} */

void main(void) {
        uint i,j;
        ReadFromEeprom(eepromAddress);
        eepromAddress = 0x0000;
        
        
        UartInit();
        
        //SendString("2"); // 發送 "2" 表示初始化完成

        P3M0 = 0xff; // 推挽
        P1M0 = 0xff;
        P3M1 = 0;
        P1M1 = 0;
        AUXR |= 0x80;

        while(1) {
                //SendString("x");
                if(flag == 1) {
                        ES = 0;
                        //SendString("3"); // 當接收到完整數據包后發送 "3"
                        IapEraseSector(0x0000);
                        for(i = 0; i < 256; i++) {
                                WriteToEeprom(eepromAddress++, buffer[ i]);
                        }
                        eepromAddress = 0x0000;
                        ReadFromEeprom(eepromAddress);
                        for(i=0;i<16;i++)
                        {
                                for(j=0;j<8;j++)
                                {
                                        SBUF = receivedData[ i][j];
                                        while(!TI);
                                        TI = 0;
                                }
                        }
                        eepromAddress = 0x0000;
                        flag = 0;
                        ES = 1;
                }
        

                Delay(1);
                T_OE = 0;
                T_STR = 0; // 鎖存無效
                for (col = 0; col < 8; col++) {
                        InputByte(receivedData[row][col]); // 輸出到 595
                }
                P1 = row; // 用 P1 口的前 4 位控制 16 行
                T_STR = 1; // 鎖存有效,此時一行的數據顯示到屏上
                T_OE = 1;
                row++;
                if (row == 16) {
                        row = 0;
                }
        }
}

void ser() interrupt 4 {
        uchar receivedByte;
        if(RI) {
                receivedByte = SBUF;
                RI = 0; // 清除接收標志位
                buffer[count++] = receivedByte;
                //SendString("6");
                if (count == 256) {
                        flag = 1;
                        count = 0;               
                        //SendString("1");
                }
        }
        if(TI) {

                TI = 0;        
        }
}

作者: WL0123    時間: 2024-11-1 21:58
欲用串口正確傳輸數據串通常需要自定義一個通訊協議,協議內容通常包括1~2個字節的數據頭標識、1~2個字節數據長度的數據、若干字節的有效數據、驗證碼以及數據尾(結束標識)等。上下位機按此通訊協議發送、接收和解析,否則無法保證通訊質量。
作者: wufa1986    時間: 2024-11-4 10:25
如果你不需要再次改變,不需要這么復雜,圖片直接做成bin文件,燒錄的時候和程序一起燒錄




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 99久久婷婷国产综合精品 | 97精品超碰一区二区三区 | 久久精品一 | 国产成人精品a视频一区www | 日韩精品一区二区三区视频播放 | 欧美自拍第一页 | 97超在线视频 | 日韩成人免费视频 | 中文字幕动漫成人 | 日日天天| 精品国产一区二区在线 | 亚洲精品乱码久久久久久黑人 | 欧美日韩在线不卡 | 中文字幕1区 | 亚洲精品9999久久久久 | 国产一区二区在线播放 | 日韩中文在线视频 | 国产视频中文字幕 | 国产免费一区二区三区免费视频 | www久久久 | 99国产精品久久久 | 一区二区精品在线 | 在线看片网站 | 国产高清在线 | 亚洲成人福利视频 | 天天色av | 成年视频在线观看 | 亚洲在线久久 | 欧美日韩在线观看一区 | 国产精品国产三级国产aⅴ中文 | 久久久久9999 | 国产精品欧美日韩 | 国产在线资源 | 亚洲午夜av久久乱码 | 精品国产乱码久久久久久闺蜜 | 成人做爰999 | 91www在线观看 | 国产精产国品一二三产区视频 | 亚洲入口 | 国产九九九九 | 爱爱免费视频 |