PWM控制输出代码.docx
《PWM控制输出代码.docx》由会员分享,可在线阅读,更多相关《PWM控制输出代码.docx(14页珍藏版)》请在冰豆网上搜索。
PWM控制输出代码
#ifndefINCLUDE_H
#defineINCLUDE_H
#include"AT89X51.h"
#include"intrins.h"
#defineucharunsignedchar
#defineuintunsignedint
#define_BV(x)(1<<(x))
#defineGET_BIT(x,y)(((x)&(1<<(y)))==0?
0:
1)/*取x变量y位的数据*/
#defineSET_BIT(x,y)((x)|=(0x0001<<(y)))/*置位x变量y位*/
#defineCLR_BIT(x,y)((x)&=~(0x0001<<(y)))/*清零x变量y位*/
#defineLET_BIT(x,y,z)((x)=(x)&(~(0x0001<<(y)))|(z)<<(y))/*置位或清零x变量y位*/
#defineF_CPU12000000UL/*cpu震荡周期*/
#definesei()(EA=1)/*开总中断*/
#definecli()(EA=0)/*关总中断*/
#endif
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#defineKEY_GLOBAL1
#include"Key.h"
staticucharkeyValueBuff;/*读取键值的缓冲区*/
staticucharkeyValueOld;/*前一次的键值*/
staticucharkeyValueTemp;/*键值中间交换变量*/
staticuintstillTimes;/*键按下保持次数*/
staticuintstillTimesMax;
staticucharget_data_1_count(ucharnumber);
staticvoidread_all_key(uchar*buff);
/*******************************************
*函数名称:
key_init(void)
*函数功能:
初始化按键扫描
*函数入口:
无
*函数出口:
无
*******************************************/
voidkey_init(void)
{
keyValueBuff=0x00;
keyValueOld=0x00;
keyValueTemp=0x00;
stillTimes=0;
stillTimesMax=FIRST_TIMES;
}
/******************************************************
*函数名称:
read_all_key(uchar*buff)
*函数功能:
扫描按键下的键,将按下的键的位置存入变量buff
*函数入口:
buff
*函数出口:
无
*******************************************************/
voidread_all_key(uchar*buff)
{
if(IN_PRESS_UP==KEY_FORCE_VALUE)//检测按下的键
READ_KEY(1,KEY_UP,*buff);
else
READ_KEY(0,KEY_UP,*buff);
if(IN_PRESS_DOWN==KEY_FORCE_VALUE)
READ_KEY(1,KEY_DOWN,*buff);
else
READ_KEY(0,KEY_DOWN,*buff);
}
/******************************************************
*函数名称:
get_key_value(void)
*函数功能:
读取键值
*函数入口:
无
*函数出口:
返回按下的有效键值
*******************************************************/
ucharget_key_value(void)
{
keyValueBuff=0x00;
read_all_key(&keyValueBuff);
keyValueTemp=keyValueBuff;
delay_us(KEY_DELAY_TIME);
read_all_key(&keyValueBuff);
/*两次读到的键盘值相同则为有效键盘值*/
if(keyValueTemp==keyValueBuff)
{
if(keyValueTemp==0)
{
keyValueOld=0;
stillTimes=0;
stillTimesMax=FIRST_TIMES;
return0;
}
elseif(keyValueOld!
=keyValueTemp)
{
stillTimes=0;
keyValueOld=keyValueTemp;
#ifCAN_MORE_PRESS
returnkeyValueTemp;
#else
if(1==get_data_1_count(keyValueTemp))
{
returnkeyValueTemp;
}
else
{
return0;
}
#endif
}
elseif(keyValueOld==keyValueTemp)
{
#ifCAN_MORE_PRESS==0
if(1!
=get_data_1_count(keyValueTemp))
{
stillTimes=0;
return0;
}
#endif
#ifCAN_REPEAT
stillTimes++;
if(stillTimes>stillTimesMax)
{
stillTimes=0;
#ifREPEAT_MODE
if(FIRST_TIMES==stillTimesMax)
{
stillTimesMax=OTHER_TIMES;
}
#endif
returnkeyValueTemp;
}
#else
stillTimes=0;
return0;
#endif
}
}
else
{
stillTimes=0;
return0;
}
return0;
}
/**********************************************************
*函数名称:
get_data_1_count(ucharnumber)
*函数功能:
计算uchar类型变量中的数量,用于检测是否多键按下
*函数入口:
number,需要检测数量的变量
*函数出口:
返回变量bumber中的数量
***********************************************************/
ucharget_data_1_count(ucharnumber)
{
registeruchari,j=0;
for(i=0;i<8;i++)
{
if((number&_BV(i)))
{
j++;
}
}
returnj;
}
/**********************************************************
*函数名称:
delay_us(uintus)
*函数功能:
毫秒级延时
*函数入口:
延时计数变量us
*函数出口:
无
***********************************************************/
voiddelay_us(uintus)
{
uchardelayi;
while(--us)
{
for(delayi=0;delayi<10;delayi++);
}
}
#include"Include.h"
#ifndefKEY_H
#defineKEY_H1
#ifndefKEY_GLOBAL
#defineKEY_EXTextern
#else
#defineKEY_EXT
#endif
#defineREAD_KEY(x,name,b)((x)?
(b|=name):
(b&=~name))
//--------------------------------用户设置区------------------------------------------
#defineCAN_MORE_PRESS0/*是否允许多键都按:
允许为;不允许为*/
#defineCAN_REPEAT1/*是否允许重复按键:
允许为;不允许为*/
#defineREPEAT_MODE1/*重复模式:
先长后短为;相同间隔为*/
#defineFIRST_TIMES200/*重复按下时,第一次间隔时间*/
#defineOTHER_TIMES25/*第二次后间隔时间(如果重复模式为时此值无效)*/
#defineKEY_DELAY_TIME20/*键盘扫描时间间隔 XXXus*/
#defineKEY_FORCE_VALUE0/*键盘有效电平,为高电平,为低电平*/
#defineIN_PRESS_UPP1_0/*1设置键端口*/
#defineIN_PRESS_DOWNP1_1/*2设置键端口*/
/*键盘重映射注:
当前结构下最大按键数为:
8;以进制中的相应位来标识*/
enumKEY_VALUE{KEY_UP=0x01,KEY_DOWN=0x02,KEY_NULL=0x00};
//------------------------------------------------------------------------------------
KEY_EXTvoidkey_init(void);//键盘扫描初始化
KEY_EXTucharget_key_value(void);//读取有效键值变量
KEY_EXTvoiddelay_us(uintus);//us级延时函数
#endif
#defineLED_GLOBAL1
#include"led.h"
externvoiddelay_us(uintus);/*声明微秒级延时函数*/
/****************************************************
*函数名称:
led_init(void)
*函数功能:
数码管初始化
*函数入口:
无
*函数出口:
无
****************************************************/
voidled_init(void)
{
//数码管显示pwm初始化值,/100
ledWrite('1',0x01,DIGITAL);
ledWrite('0',0x02,DIGITAL);
ledWrite('0',0x03,DIGITAL);
}
/***********************************************************
*函数名称:
ledWrite(ucharc,ucharn,ucharmod)
*函数功能:
向第n个数码管写mod模式的内容c
*函数入口:
c为要显示的内容,显示数字时,调用入口应输入数字字符;
n为要显示的数码管编号;mod为要显示的模式
*函数出口:
无
*************************************************************/
voidledWrite(ucharc,ucharn,ucharmod)
{
if(CHARACTER==mod)//为任意字段显示
LED=c;
elseif(DIGITAL==mod)
LED=segLedCode[c-'0'];
switch(n)
{
case0x01:
{
LED_CS1=CS_FORCE_VALUE;
delay_us(10);
LED_CS1=0;//~CS_FORCE_VALUE
break;
}
case0x02:
{
LED_CS2=CS_FORCE_VALUE;
delay_us(10);
LED_CS2=0;
break;
}
case0x03:
{
LED_CS3=CS_FORCE_VALUE;
delay_us(10);
LED_CS3=0;
break;
}
default:
break;
}
}
/*********************************************************
*驱动名称:
七段LED数码管驱动
*功能:
适用于带个锁存器LS373的段数码管显示
*修改:
修改驱动使其适用于三个数码管显示
*版本:
V
*kxm
*时间:
.06.11
*********************************************************/
#ifndefLED_H
#defineLED_H1
#include"Include.h"
#ifndefLED_GLOBAL
#defineLED_EXTextern
#else
#defineLED_EXT
#endif
#defineCS_FORCE_VALUE1/*74LS373片选有效电平*/
//***************数码管端口定义****************************
#defineLEDP0/*定义LED数据端口*/
#defineLED_CS1P2_0/*74LS373锁存器片选端口*/
#defineLED_CS2P2_1/*74LS373锁存器片选端口*/
#defineLED_CS3P2_2/*74LS373锁存器片选端口*/
//*********************************************************
enumSEG_DISPLAY_MOD{DIGITAL=0x00,CHARACTER=0x01};/*数码管输出模式,数字或任意字段显示*/
/*高电平驱动*/
#ifdefLED_GLOBAL
ucharsegLedCode[10]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x73};
/*数码管数码译码数组,led6~led0==a~g,code1~10==0~9*/
#endif
LED_EXTvoidled_init(void);/*数码管初始化*/
LED_EXTvoidledWrite(ucharc,ucharn,ucharmod);/*向第n个数码管写mod模式的内容c*/
#endif
#definePWM_GLOBAL1
#include"pwm.h"
/*****************************************************
*函数名称:
pwm_init(void)
*函数功能:
PWM初始化,设置定时器
*函数入口:
无
*函数出口:
无
*****************************************************/
voidpwm_init(void)//12M
{
TMOD=0x20;//定时器模式
TL1=255-10;//1ms
TH1=255-10;
ET1=1;//定时器边沿触发
TR1=1;//开定时器中断
pwmPeriodCont=0x00;
pwmH=0x01;
}
/*****************************************************
*函数名称:
voidpwm_set(constucharNewPwmValue)
*函数功能:
PWM占空比设置
*函数入口:
无
*函数出口:
无
*****************************************************/
voidpwm_set(ucharNewPwmValue)
{
if((NewPwmValue>=1)&&(NewPwmValue<=99))//一个周期里
{
pwmH=NewPwmValue;
}
else//若占空比不在...99范围内则输出一个尖脉冲
{
pwmH=0x01;
}
}
/*****************************************************
*函数名称:
pwmProduce(void)
*函数功能:
定时器溢出中断设置
*函数入口:
无
*函数出口:
无
*****************************************************/
voidpwmProduce(void)interrupt3
{
pwmPeriodCont++;//PWM定时周期计数加
if(pwmPeriodCont<=pwmH)
PWM_OUT=1;//高电平从到...PWM_H
else//剩下的为低电平时间
{
PWM_OUT=0;
if(pwmPeriodCont>=PWM_Period)//一个频率周期结束
{
pwmPeriodCont=0;
}
}
}
/***********************************************
*驱动功能:
产生pwm,12MHZ晶振下,总周期为*1ms
*版本:
.0.1
*lhw
*时间:
.06.11
***********************************************/
#ifndefPWM_H
#definePWM_H
#include"Include.h"
#ifndefPWM_GLOBAL
#definePWM_EXTextern
#else
#definePWM_EXT
#endif
#definePWM_Period100//100%占空比时标数
//*******************端口定义**********************
sbitPWM_OUT=P1^2;/*pwm输出端口映射*/
//*************************************************
PWM_EXTucharpwmPeriodCont;//PWM占空比计数器
PWM_EXTucharpwmH;
PWM_EXTvoidpwm_init(void);/*PWM初始化,设置定时器*/
PWM_EXTvoidpwm_set(constucharNewPwmValue);/*PWM占空比设置*/
#endif
#include"led.h"
#include"key.h"
#include"pwm.h"
staticucharpwmScale;//pwm占空比,1~99
voidmain()
{
ucharkeyValue;
pwm_init();//初始化pwm,pwm高电平默认值为
key_init();
led_init();
pwmScale=0x01;//初始化占空比变量,初始值为
sei();
while
(1)
{
keyValue=get_key_value();
if(keyValue!
=KEY_NULL)
{
if(keyValue==KEY_UP)
{
if(pwmScale<99)
pwmScale++;
}
if(keyValue==KEY_DOWN)
{
if(pwmScale>1)
pwmScale--;
}
pwm_set(pwmScale);
ledWrite(pwmScale%10+'0',0x01,DIGITAL);//显示占空比个位
ledWrite(pwmScale/10+'0',0x02,DIGITAL);//显示占空比十位
}
}
}