用軟件通過串口控制PWM并用LED顯示PWM值:本人已調(diào)試成功,用易語言做的串口發(fā)送工具,發(fā)送PWM值,并在LED上顯示PWM值,外加L298N可控制直流電機,也可用于舵機控制,但舵機控制還有點問題,波形不正常!現(xiàn)上傳源碼:/***********************************************************************************
* 標(biāo)題: RS232串口通信試驗(接受與發(fā)送) *
* *
* 1.通過本例程了解串口的基本原理及使用 ,理解并掌握對串口進(jìn)行初始化 *
* *
* 2.請使用串口調(diào)試助手(Baud 4800、數(shù)據(jù)位8、停止位1、效驗位無)做為上位機來做收發(fā)試驗。
* 在調(diào)試助手字符串輸入框中輸入數(shù)字和字符,按發(fā)送按鈕,然后觀察接受窗口的變化。也可以用
* 調(diào)試助手自動循環(huán)發(fā)送。 *
* *
* 請學(xué)員認(rèn)真消化本例程,學(xué)會用C語言操作串口 *
*************************************************************************************/
#include <REG52.H>
#include <intrins.h>
#define uchar unsigned char
sbit BEEP = P1^4;
sbit P21=P2^1; //PWM輸出1
sbit P20=P2^0; //PWM輸出2
sbit P26=P2^6; //用于L298N,控制直流電機
sbit P27=P2^7; //用于L298N,控制直流電機
bit Flag;
sbit LS138A = P2^2; //定義138譯碼器的輸入A腳由P2.2控制
sbit LS138B = P2^3; //定義138譯碼器的輸入腳B由P2.3控制
sbit LS138C = P2^4; //定義138譯碼器的輸入腳C由P2.4控制
unsigned int ReData,SenData;
unsigned int i,LedNumVal=1 ;
unsigned int LedOut[10];
unsigned int PWM_T=15; //占空比控制變量
void delay(unsigned int i); //函數(shù)聲名
// 此表為 LED 的字模
//unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
//此表為 LED 的字模, 共陰數(shù)碼管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
///////////////////串口輸出//////////////////////
void fun_SclMode(uchar ReData)
{
unsigned int LedNumVal;
LedNumVal=ReData;
PWM_T=LedNumVal;
LedOut[0]=Disp_Tab[LedNumVal%10000/1000]; //千位
LedOut[1]=Disp_Tab[LedNumVal%1000/100]|0x80; //百位帶小數(shù)點
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10]; //個位
for( i=0; i<9; i++) //實現(xiàn)8位動態(tài)掃描循環(huán)
{
P0 = LedOut; //將字模送到P0口顯示
switch(i) //使用switch 語句控制位選 也可以是用查表的方式 學(xué)員可以試著自己修改
{
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
}
delay(5);
}
}
//////////////////////////////////////////////////////////
timer0() interrupt 1 //定時器0中斷服務(wù)程序
{
static unsigned int tt ; //tt用來保存當(dāng)前時間在一秒中的比例位置
tt++; //每200微秒增加1
if(tt==100) //20毫秒的時鐘周期
{ tt=0; //使tt=0,開始新的PWM周期
P20=0;
P21=0;
}
if(PWM_T==tt) //按照當(dāng)前占空比切換輸出為高電平
{
P20=1;
P21=1;
}
}
//////////////////////////////////////////////////////
void main (void)
{
SCON = 0x50; //REN=1允許串行接受狀態(tài),串口工作模式1
TMOD|=0x22; // 定時器0定時器1工作方式2
PCON|= 0x80; //用于12M
// PCON|= 0x00; //用于11.0592
//TH1 = 0xFD; //baud*2 /* reload value 19200、數(shù)據(jù)位8、停止位1。效驗位無 (11.0592)
TH1 = 0xF3; // //baud*2 /* 波特率4800、數(shù)據(jù)位8、停止位1。效驗位無 (12M)
TL1 = 0xF3;
TH0=56; //寫入預(yù)置初值56到定時器0,使200微秒溢出一次(12MHz)
TL0=56; //寫入預(yù)置值,數(shù)字越大,平率越快
TR1 = 1;
TR0 = 1;
ES = 1; //開串口中斷
EA = 1; // 開總中斷
ET0 = 1; //允許定時器0中斷
BEEP=1;
// IE = 0x0;
P26=0;
P27=1;
while(1)
{
if (Flag==1)
{
SBUF=SenData; //SUBF接受/發(fā)送緩沖器
while(TI==0);
TI=0;
Flag=0;
}
fun_SclMode(ReData); //串口
}
}
/****************************************************
串口中斷程序
******************************************************/
void ser_int (void) interrupt 4 using 1
{
if(RI == 1) //RI接受中斷標(biāo)志
{
RI = 0; //清除RI接受中斷標(biāo)志
ReData = SBUF; //SUBF接受/發(fā)送緩沖器
SenData=ReData;
Flag=1;
}
}
/***************************************************************************
* *
* 延時程序 *
****************************************************************************/
void delay(unsigned int i)
{
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--);
}