|
文件夾 e:\dpj\20210101
目標(biāo) STC15W4K32S4
proteus 新建單片機(jī) 串口 分壓調(diào)節(jié)電壓源 更改單片機(jī)主頻為11059200
虛擬串口軟件安裝及配置
單片機(jī)使用COM4 串口調(diào)試器使用COM3 波特率 115200
ADC讀取電壓數(shù)據(jù)正常 P1.0 P1.1
串口通訊測(cè)試正常 ADC 通過(guò)可變電阻調(diào)節(jié)電壓后 模擬量變化發(fā)送串口
串口通訊測(cè)試正常 中斷接收<>之間字符,回送 因地址空間,字符個(gè)數(shù)<10
程序運(yùn)行時(shí)間以protues左下角的運(yùn)行時(shí)間為準(zhǔn) 見(jiàn)截圖
定時(shí)器設(shè)置及中斷處理 以1ms為周期,每3000ms在串口發(fā)送字符
串口命令設(shè)置定時(shí)器發(fā)送數(shù)據(jù)到串口的時(shí)間間隔 <后的第一個(gè)字符為A 第二個(gè)為數(shù)字 表示間隔秒數(shù)
仿真原理圖如下(STC15W4K32S4單片機(jī)proteus仿真工程文件可到本帖附件中下載)
運(yùn)行畫面.jpg (555.97 KB, 下載次數(shù): 95)
下載附件
2021-1-3 14:15 上傳
單片機(jī)源程序如下:
- /*---------------------------------------------------------------------*/
- /* --- STC MCU Limited ------------------------------------------------*/
- /* --- STC15F4K60S4 系列 定時(shí)器1用作串口1的波特率發(fā)生器舉例------------*/
- /* 如果要在程序中使用此代碼,請(qǐng)?jiān)诔绦蛑凶⒚魇褂昧薙TC的資料及程序 */
- /* 如果要在文章中應(yīng)用此代碼,請(qǐng)?jiān)谖恼轮凶⒚魇褂昧薙TC的資料及程序 */
- /*---------------------------------------------------------------------*/
- //本示例在Keil開發(fā)環(huán)境下請(qǐng)選擇Intel的8058芯片型號(hào)進(jìn)行編譯
- //若無(wú)特別說(shuō)明,工作頻率一般為11.0592MHz
- #include "STC15Fxxxx.H"
- //#include "reg51.h"
- #include <stdio.h>
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- //typedef unsigned int u16; //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
- //typedef unsigned char u8;
- #define FOSC 11059200L //系統(tǒng)頻率
- #define BAUD 115200 //串口波特率
- #define NONE_PARITY 0 //無(wú)校驗(yàn)
- #define ODD_PARITY 1 //奇校驗(yàn)
- #define EVEN_PARITY 2 //偶校驗(yàn)
- #define MARK_PARITY 3 //標(biāo)記校驗(yàn)
- #define SPACE_PARITY 4 //空白校驗(yàn)
- #define PARITYBIT NONE_PARITY //定義校驗(yàn)位
- /* STC15Fxxxx.H中已定義
- //sfr P0M1 = 0x93;
- //sfr P0M0 = 0x94;
- //sfr P1M1 = 0x91;
- //sfr P1M0 = 0x92;
- //sfr P2M1 = 0x95;
- //sfr P2M0 = 0x96;
- //sfr P3M1 = 0xb1;
- //sfr P3M0 = 0xb2;
- //sfr P4M1 = 0xb3;
- //sfr P4M0 = 0xb4;
- //sfr P5M1 = 0xC9;
- //sfr P5M0 = 0xCA;
- //sfr P6M1 = 0xCB;
- //sfr P6M0 = 0xCC;
- //sfr P7M1 = 0xE1;
- //sfr P7M0 = 0xE2;
- //sfr AUXR = 0x8e; //輔助寄存器
- //sfr P_SW1 = 0xA2; //外設(shè)功能切換寄存器1
- */
- #define S1_S0 0x40 //P_SW1.6
- #define S1_S1 0x80 //P_SW1.7
- #define ADC_POWER 0x80 //ADC電源控制位
- #define ADC_FLAG 0x10 //ADC完成標(biāo)志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540個(gè)時(shí)鐘
- #define ADC_SPEEDL 0x20 //360個(gè)時(shí)鐘
- #define ADC_SPEEDH 0x40 //180個(gè)時(shí)鐘
- #define ADC_SPEEDHH 0x60 //90個(gè)時(shí)鐘
- //sbit P22 = P2^2;
- unsigned int ch;a,b;
- unsigned int dd=0;
- unsigned int cc=0;
- unsigned int cc0=0;
- unsigned int cc1=0;
- unsigned int cc00=0;
- unsigned int cc01=0;
- unsigned int cc10=0;
- unsigned int cc11=0;
- unsigned int time0count0 = 0 ;
- unsigned int time0count1 = 0 ;
- unsigned int time0count = 3000 ;
- bit busy;
- char receivechar = 0;
- int receive_count = 0;
- int received = 0;
- WORD receivestr[10];
- void InitUart();
- void InitADC();
- void Timer0Init();
- void SendData(BYTE dat);
- void SendString(char *s);
- void serial_put_uint(unsigned int number);
- void Delay(WORD n);
- //void ShowResult(BYTE ch);
- unsigned int GetADCResultint(BYTE ch);
- void main()
- {
- int initreceivestrcount=0;
- unsigned int tt0=0,tt1=0;
- // unsigned int d1,d2,d3,i;
- unsigned int i=0;
- if (i == 0 ) //初始化tt0 tt1 P0 -P7 數(shù)據(jù)
- {
- /*
- 例如將P1M0=0X60和P1M1=0X00譯成bai二進(jìn)制代碼是
- P1M0=0110 0000,duP1M1=0000 0000.
- 按照I/O口工作模式設(shè)置zhi規(guī)定
- 都為0時(shí)為準(zhǔn)雙向口(dao傳統(tǒng)8051單片機(jī)zhuanI/O口模式)
- 為0,1時(shí)為推挽(shu強(qiáng)上拉輸出),
- 為1,0時(shí)為高阻(僅輸入),
- 為1,1時(shí)為開漏(內(nèi)部上拉斷開,須外加上拉電阻)
- 你選擇的是P1M0和P1M1所以針對(duì)的是P1口的操作,
- 將兩個(gè)二進(jìn)制代碼一位位的比較可知:P1.0~P1.4及P1.7都為0,
- 故這些I/O口設(shè)置的是標(biāo)準(zhǔn)狀態(tài);P1.5和P1.6為高阻態(tài)
- (P1M0上的第六位和第七位都為1,P1M1上的第六位和第七位都是0。1,0時(shí)為高阻)
- */
- tt0=16640;
- tt1=tt0/256;
- P0M0 = 0x00;
- P0M1 = 0x00;
- P1M0 = 0x00;
- P1M1 = 0x03;
- P2M0 = 0x00;
- P2M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P4M0 = 0x00;
- P4M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P6M0 = 0x00;
- P6M1 = 0x00;
- P7M0 = 0x00;
- P7M1 = 0x00;
- }
- InitUart(); //初始化串口
- //printf ("20200102 第一次調(diào)試 a 1 取左字節(jié) a %d A/256=A %d C51\n" , tt0,tt1 ); /* ?? "Hello C51 " */
- SendString("20200102 第二次調(diào)試 \r\n");
- initreceivestrcount=0;
- while (initreceivestrcount<10) //初始化 receivestr
- {
- receivestr[initreceivestrcount]=0;
- initreceivestrcount = initreceivestrcount + 1 ;
- }
- //printf ("Hello"); //printf 不能使用 編譯通過(guò) 不能仿真運(yùn)行
- InitADC(); //初始化ADC
- Timer0Init(); //定時(shí)器0初始化
- /* 除法測(cè)試
- //printf ("Hello ADC 第y次調(diào)試 a 1 加代碼a %d A/256=A %d C51\n" , tt0,tt1 );
- // sprintf(str," receive %d \r\n",receivechar);
- // SendString(str);
- // sprintf(str," d1 %d a \r\n",tt0);
- // SendString(str);
- // sprintf(str," d2 %d a \r\n",tt1);
- // SendString(str);
- // sprintf(str," d3 %d a \r\n",d3);
- // SendString(str);
- */
- SendString("c STC15W4kS32\r\n Uart Test !\r\n");
- while(1)
- {
- if (received == 1) // 在串口接收預(yù)定義字符后回送 20210103 增加控制定時(shí)顯示功能
- {
- /* 除法測(cè)試及sprintf
- // SendString("\r\n");
- // d1 = receivechar;
- // d2 = d1 ;
- // d3=d2*256;
- // d3=d1-d3;
- // sprintf(str," receive %d a\r\n",receivechar);
- // SendString(str);
- // sprintf(str," d1 %d b \r\n",d1);
- // SendString(str);
- // sprintf(str," d2 %d c \r\n",d2);
- // SendString(str);
- // sprintf(str," d3 %d d \r\n",d3);
- // SendString(str);
- // SendString(receivestr);receivechar
- */
- serial_put_uint(receivechar);
- SendString(" start ");
- //serial_put_uint(11);
- for (i=0;i<receive_count;i++)
- {
- SendData(receivestr[i]);
- }
- SendString(" COUNT= ");
- serial_put_uint(receive_count);
- receive_count = 0 ;
- if (receivestr[1] == 65 )
- {
- time0count = ( receivestr[2] - 48 ) * 1000 ;
- SendString(" \r\n 串口設(shè)定 time0 ");
- serial_put_uint(time0count/1000);
- SendString(" 秒定時(shí) ");
- }
- SendString(" \r\n");
- received = 0 ;
- }
- if (time0count0 != time0count1) // 串口設(shè)定的秒定時(shí)
- {
- SendString(" time0 ");
- serial_put_uint(time0count/1000);
- SendString(" 秒定時(shí) 執(zhí)行 ");
- serial_put_uint(time0count0);
- SendString(" \r\n ");
- time0count1 = time0count0;
- }
- b=b+1;
- dd=0;
- cc00 = GetADCResultint(dd); //讀取ADC 0 P1.0 數(shù)據(jù)
- if (cc01 != cc00) // ADC 0 P1.0 數(shù)據(jù)變化發(fā)送串口
- {
- SendString(" ADC ");
- // serial_put_uint(b);
- SendString(" ch ");
- serial_put_uint(dd);
- SendString(" new ");
- serial_put_uint(cc00);
- SendString(" old ");
- serial_put_uint(cc01);
- SendString(" end \r\n");
- //printf (" ADC %d ch %d :0x %x 0d %d \n", b,dd,cc00,cc01 );
- cc01 = cc00;
- }
- dd=1;
- cc10 = GetADCResultint(dd); //讀取ADC 1 P1.1 數(shù)據(jù)
- if (cc11 != cc10) // ADC 1 P1.1 數(shù)據(jù)變化發(fā)送串口
- {
- SendString(" ADC ");
- // serial_put_uint(b);
- SendString(" ch ");
- serial_put_uint(dd);
- SendString(" new ");
- serial_put_uint(cc10);
- SendString(" old ");
- serial_put_uint(cc11);
- SendString(" end \r\n");
- //printf (" ADC %d ch %d :0x %x 0d00 %d \n", b,dd,cc10,cc11 );
- cc11=cc10;
- }
- dd=0;
- if (b>10000) b=0;
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Timer0Init
- * 函數(shù)功能 : 定時(shí)器0初始化
- * 輸 入 : 無(wú)
- * 輸 出 : 無(wú)
- *******************************************************************************/
- void Timer0Init()
- {
- TMOD|=0X01;//選擇為定時(shí)器0模式,工作方式1,僅用TR0打開啟動(dòng)。
- TH0=0XFC; //給定時(shí)器賦初值,定時(shí)1ms
- TL0=0X18;
- ET0=1;//打開定時(shí)器0中斷允許
- EA=1;//打開總中斷
- TR0=1;//打開定時(shí)器
- }
- /*----------------------------
- 初始化串口
- ----------------------------*/
- void InitUart()
- {
- // ACC = P_SW1;
- // ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0
- // P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD)
-
- // ACC = P_SW1;
- // ACC &= ~(S1_S0 | S1_S1); //S1_S0=1 S1_S1=0
- // ACC |= S1_S0; //(P3.6/RxD_2, P3.7/TxD_2)
- // P_SW1 = ACC;
- //
- // ACC = P_SW1;
- // ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=1
- // ACC |= S1_S1; //(P1.6/RxD_3, P1.7/TxD_3)
- // P_SW1 = ACC;
- #if (PARITYBIT == NONE_PARITY)
- SCON = 0x50; //8位可變波特率
- #elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
- SCON = 0xda; //9位可變波特率,校驗(yàn)位初始為1
- #elif (PARITYBIT == SPACE_PARITY)
- SCON = 0xd2; //9位可變波特率,校驗(yàn)位初始為0
- #endif
- AUXR = 0x40; //定時(shí)器1為1T模式
- TMOD = 0x00; //定時(shí)器1為模式0(16位自動(dòng)重載)
- TL1 = (65536 - (FOSC/4/BAUD)); //設(shè)置波特率重裝值
- TH1 = (65536 - (FOSC/4/BAUD))>>8;
- TR1 = 1; //定時(shí)器1開始啟動(dòng)
- ES = 1; //使能串口中斷
- EA = 1;
-
-
-
- // SCON = 0x5a; //設(shè)置串口為8位可變波特率
- //#if URMD == 0
- // T2L = (65536 - (FOSC/4/BAUD));
- // T2H = (65536 - (FOSC/4/BAUD)) >> 8;
- // AUXR = 0x14; //T2為1T模式, 并啟動(dòng)定時(shí)器2
- // AUXR |= 0x01; //選擇定時(shí)器2為串口1的波特率發(fā)生器
- //#elif URMD == 1
- // AUXR = 0x40; //定時(shí)器1為1T模式
- // TMOD = 0x00; //定時(shí)器1為模式0(16位自動(dòng)重載)
- // TL1 = (65536 - (FOSC/4/BAUD));
- // TH1 = (65536 - (FOSC/4/BAUD)) >> 8;
- // TR1 = 1; //定時(shí)器1開始啟動(dòng)
- //#else
- // TMOD = 0x20; //設(shè)置定時(shí)器1為8位自動(dòng)重裝載模式
- // AUXR = 0x40; //定時(shí)器1為1T模式
- // TH1 = TL1 = (256 - (FOSC/32/BAUD));
- // TR1 = 1;
- //#endif
- }
- /*----------------------------
- 初始化ADC
- ----------------------------*/
- void InitADC()
- {
- P1M0 =1;
- P1M1 =0;
- P1 = 0Xff;
- P1ASF = 0xff; //設(shè)置P1口為AD口
- ADC_RES = 0; //清除結(jié)果寄存器
- ADC_RESL = 0; //清除結(jié)果寄存器
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
- Delay(2); //ADC上電并延時(shí)
- }
- /*----------------------------
- 讀取ADC結(jié)果 20210101 注釋GetADCResult 用GetADCResultint代替
- ----------------------------*/
- unsigned int GetADCResultint(BYTE ch)
- {
- unsigned int ret=0;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
- _nop_(); //等待4個(gè)NOP
- _nop_();
- _nop_();
- _nop_();
- while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉(zhuǎn)換完成
- ADC_CONTR &= ~ADC_FLAG; //Close ADC
- ret = ADC_RES*4 + ADC_RESL;
- return ret; //返回ADC結(jié)果
- }
- /*----------------------------
- UART 中斷服務(wù)程序
- -----------------------------*/
- void Uart() interrupt 4
- {
- if (RI)
- {
- RI = 0; //清除RI位
- receivechar = SBUF; //P0顯示串口數(shù)據(jù)
- if ( receivechar == 60 ) receive_count = 0 ;
- if ((receive_count<9) && ( receivechar != 62 )&&(received == 0 ))
- {
- receivestr[receive_count] = receivechar;
- receivestr[receive_count+1] = 0;
- receive_count = receive_count + 1 ;
-
- }
- else
- {
- received = 1;
- // while (initreceivestrcount<10)
- // {
- // receivestr[initreceivestrcount]=0;
- // initreceivestrcount = initreceivestrcount + 1 ;
- // }
-
- }
- // SendData(receivechar);
- // P22 = RB8; //P2.2顯示校驗(yàn)位
- }
-
- if (TI)
- {
- TI = 0; //清除TI位
- busy = 0; //清忙標(biāo)志
- }
- }
- void Timer0() interrupt 1
- {
- static u16 itime0;
- TH0=0XFC; //給定時(shí)器賦初值,定時(shí)1ms
- TL0=0X18;
- itime0++;
- if(itime0==time0count)
- {
- itime0=0;
- time0count0 = time0count0 + 1;
- if ( time0count0 > 20 ) time0count0 = 0;
- }
- }
- /*----------------------------
- 發(fā)送串口數(shù)據(jù)
- ----------------------------*/
- void SendData(BYTE dat)
- {
- while (busy); //等待前面的數(shù)據(jù)發(fā)送完成
- ACC = dat; //獲取校驗(yàn)位P (PSW.0)
- // if (P) //根據(jù)P來(lái)設(shè)置校驗(yàn)位
- // {
- //#if (PARITYBIT == ODD_PARITY)
- // TB8 = 0; //設(shè)置校驗(yàn)位為0
- //#elif (PARITYBIT == EVEN_PARITY)
- // TB8 = 1; //設(shè)置校驗(yàn)位為1
- //#endif
- // }
- // else
- // {
- //#if (PARITYBIT == ODD_PARITY)
- // TB8 = 1; //設(shè)置校驗(yàn)位為1
- //#elif (PARITYBIT == EVEN_PARITY)
- // TB8 = 0; //設(shè)置校驗(yàn)位為0
- //#endif
- // }
- busy = 1;
- SBUF = ACC; //寫數(shù)據(jù)到UART數(shù)據(jù)寄存器
- }
- /*----------------------------
- 發(fā)送字符串
- ----------------------------*/
- void SendString(char *s)
- {
- // EA = 0 ;
- // ES = 0 ;
- while (*s) //檢測(cè)字符串結(jié)束標(biāo)志
- {
- SendData(*s++); //發(fā)送當(dāng)前字符
- }
- // EA = 1 ;
- // ES = 1 ;
- }
- void serial_put_uint(unsigned int number)
- {
- unsigned int i;
- unsigned int nTmp;
- // *s++ =num/10 +'0';
- //*s++=num%10 +'0';
- //*s =0;
-
- //感覺(jué)這寫法怪怪的嗎?干嘛不for(i=1;i<5;i++) 因?yàn)檫@樣不需要使用庫(kù)函數(shù)pow()
- for(i=10000;i>=1;i=i/10)
- {
- nTmp = number/i;
- if(nTmp >=1 ) SendData((unsigned char)(nTmp%10 + 0x30));
- }
- }
- /*----------------------------
- 軟件延時(shí)
- ----------------------------*/
- void Delay(WORD n)
- {
- WORD x;
- while (n--)
- {
- x = 5000;
- while (x--);
- }
- }
復(fù)制代碼
51hei.png (13.98 KB, 下載次數(shù): 99)
下載附件
2021-1-3 14:17 上傳
所有資料51hei提供下載:
20210103a.rar
(580.92 KB, 下載次數(shù): 243)
2021-1-3 13:45 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|