/******************************************************************************FileName : main.cAuthor : 9longDate : 2010.5.11Target : STC89C51Crystal : 12M*******************************************************************************模块功能 : 用定时中断调试PWM可调模块,可以接在直流电机上调速******************************************************************************/#include <REG52.H>/*-----------------------------------宏定义----------------------------------*///键值表-----------------------------------------------------------------------#define NOKEY 0#define KEY1 128#define KEY2 129#define KEY3 131#define KEY4 135#define KEY5 64#define KEY6 65#define KEY7 67#define KEY8 71#define KEY9 32#define KEY10 33#define KEY11 35#define KEY12 39#define KEY13 16#define KEY14 17#define KEY15 19#define KEY16 23//数码管位驱动-----------------------------------------------------------------#define DIG0 0xfe#define DIG1 0xfd#define DIG2 0xfb#define DIG3 0xf7#define DIG4 0xef#define DIG5 0xdf#define DIG6 0xbf#define DIG7 0x7f//字符表-----------------------------------------------------------------------#define CODE0 0xc0#define CODE1 0xf9#define CODE2 0xa4#define CODE3 0xb0#define CODE4 0x99#define CODE5 0x92#define CODE6 0x82#define CODE7 0xf8#define CODE8 0x80#define CODE9 0x90#define CODEA 0x88#define CODEB 0x83#define CODEC 0xc6#define CODED 0xa1#define CODEE 0x86#define CODEF 0x8e#define CODEH 0x89#define CODEP 0x8c#define POINT 0x7f#define CODE_ 0xf7#define CODENO 0xff//LED控制位(PWM模块接口定义,根据自已的需要更改)------------------------sbit LED = P1^2;/*---------------------------------变量定义----------------------------------*/code const unsigned char NUMBER_CODE[10] = {CODE0,CODE1,CODE2,CODE3,CODE4,CODE5,CODE6,CODE7,CODE8,CODE9};code const unsigned char LED_DIG[8] = {DIG0,DIG1,DIG2,DIG3,DIG4,DIG5,DIG6,DIG7};unsigned char LED_SEG[8] = {0}; //显示缓冲区 unsigned char flag_10ms = 0; //10ms标志位unsigned char last_key = 0;unsigned char key = 0;unsigned char PWM_CYCLE = 0; //PWM的周期unsigned char PWM_ON = 0; //PWM的占空比/******************************************************************************函数名称:Delay1ms()函数功能: 延时count*1ms输入参数:count,无符号整型,最多计65535ms count输出参数:无全局变量:无******************************************************************************/void Delay1ms(unsigned int count){ unsigned int i=0; unsigned int j=0; for(i=0;i<count;i++) for(j=0;j<120;j++);}/******************************************************************************函数名称:DisplayCode()函数功能: 数码管显示缓冲,送段驱动输入参数:x,无符号整型,最多显示65535输出参数:无全局变量:LED_SEG[i],NUMBER_CODE[i]******************************************************************************/void DisplayCode(unsigned int x){ unsigned char m=0; LED_SEG[7]=CODEF; LED_SEG[6]=CODE_; LED_SEG[5]=CODE_; while(x>=10000){x=x-10000;m++;}LED_SEG[4]=NUMBER_CODE[m];m=0; while(x>=1000) {x=x-1000;m++;} LED_SEG[3]=NUMBER_CODE[m];m=0; while(x>=100) {x=x-100;m++;} LED_SEG[2]=NUMBER_CODE[m];m=0; while(x>=10) {x=x-10;m++;} LED_SEG[1]=NUMBER_CODE[m];m=0; while(x>=1) {x=x-1;m++;} LED_SEG[0]=NUMBER_CODE[m];m=0;}/******************************************************************************函数名称:ReadKey()函数功能: 读取4*4矩阵按键的键值输入参数:无输出参数:按键的键值全局变量:无******************************************************************************/unsigned char ReadKey(void){ unsigned char cord_x=0; //定义行和列 unsigned char cord_y=0; P3 = 0x0f; //行扫描,高四位输出低电平,低四位高电平输入状态,进行行扫描 cord_x = (P3 & 0x0f); //行扫描值送入cord_x if(cord_x == 0x0f) return (0); //无键按下,返回0 else //有键按下,则继续进行按键扫描 { P3 = (cord_x | 0xf0); //列扫描,高四位高电平输入状态,低四位扫描到的行进行回扫,那一行输出低电平 cord_y = P3 & 0xf0; //列扫描值送入cord_y return (~cord_x + ~cord_y); //返回组合码 }}/******************************************************************************函数名称:Play()函数功能: 每10ms刷新显示和扫描按键输入参数:无输出参数:无全局变量:flag_10ms,last_key,key,LED_DIG[i],LED_SEG[i]******************************************************************************/ void Play(void){ unsigned char i=0; while(!flag_10ms); //有标志位则退出循环 flag_10ms = 0; //标志位清零 for(i=0;i<8;i++) //数码管显示 { P2 = LED_DIG[i]; //位驱动 P0 = LED_SEG[i]; //段驱动 Delay1ms(1); //延时1ms } P2 = 0xff; //清显示 P0 = 0xff; last_key = key; //记住上次键值 key = ReadKey(); //读新键值}/******************************************************************************函数名称:Timer1()函数功能: 定时器0定时0.1ms输入参数:无输出参数:无全局变量:PWM_ON为占空比,PWM_CYCLE为周期******************************************************************************/void timer1(void) interrupt 3 { static unsigned char pwm=0; pwm++; if(pwm==PWM_ON) LED=1; //灯灭 if(pwm==PWM_CYCLE) { pwm=0; if(PWM_ON!=0) LED=0; //灯亮 }}/******************************************************************************函数名称:Timer0()函数功能: 定时器0定时10ms输入参数:无输出参数:无全局变量:flag_10ms******************************************************************************/void Timer0(void) interrupt 1 { TH0 = 0xd8; //定时10ms TL0 = 0xf0; flag_10ms = 1; //设定标志位}/******************************************************************************函数名称:main()函数功能: 主函数输入参数:无输出参数:无全局变量:last_key,key,PWM_ON为占空比,PWM_CYCLE为周期******************************************************************************/void main (void){ TMOD = 0x21; //time0方式1,timer1方式2 EA = 1; //开总中断 ET0 = 1; //开定时器0中断 TR0 = 1; //启动定时器0 ET1 = 1; //开定时器1中断 TR1 = 1; //启动定时器1 TH1 = 0x9c; //定时0.1ms TL1 = 0x9c; PWM_ON= 1; //设定占空比为1/10; PWM_CYCLE = 10; //周期为10*0.1ms,可调,随便设置 P2 = 0x00; /*ULN2003有反向作用,ULN2003输出为高电平*/ for(;;) { Play(); DisplayCode(PWM_ON); if((last_key == NOKEY) && (key == KEY1)) { PWM_ON++; if(PWM_ON>=10) PWM_ON=0; //调占空比 } } }