简单的PWM程序写了一个简单的PWM程序,给初学者,PWM+数字电表
用QL200的VR1作输入来调节占空比,并用D10,D11来显示VR1输入到RA0的电压,
//////////////////////////////////////////////////
// Author : Toby
// Date : 2009/01/21
// Function : 程序用于使CCP1模块产生分辨率为10位的PWM波形,占空比可调,
// MCU : PIC16F877A
// ...
写了一个简单的PWM程序,给初学者,PWM+数字电
用QL200的VR1作输入来调节占空比,并用D10,D11来显示VR1输入到RA0的电压,
//////////////////////////////////////////////////
// Author : Toby
// Date : 2009/01/21
// Function : 程序用于使CCP1模块产生分辨率为10位的PWM波形,占空比可调,
// MCU : PIC16F877A
// C Compiler : PICC 8.05
// IDE : MPLAB IDE v8.10
/////////////////////////////////////////////////
#include
__CONFIG(0x3f3a);
union adres //定义一个共用体,用于存放10位A/D转换的结果
{int y1;
unsigned char adre[2];
}adresult;
const char TABLE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0X82,0XF8,0X80,0X90}; //定义常数0-9的数据表格
void CCP1INIT(void);
void interrupt clkint(void);
void adinitial_voltage(void);
void display_voltage(void);
void ini(void);
void delay(unsigned char x);
unsigned char QC,TONOFF=5;
unsigned int ad_data=0;
//主程序
main()
{
ini();
CCP1INIT(); //CCP1模块的PWM工作方式初始化
T2CON=4; //打开TMR2,且使其前预分频为1:1,后分频比为1:1,但在这个程序中后分频比用不上
while(1)
{
CCPR1L=TONOFF; //CCPR1L与DC1B1与DC1B0共同组成占空比的可调范围,以当前程序为例,则占空比为DC1B<9:0)*Tosc*TMR2预分频
QC=0;
display_voltage();
adinitial_voltage();
}
}
void CCP1INIT() //CCP1模块的PWM工作方式初始化子程序*/
{
CCP1CON=0X3C; //设置CCP1模块为PWM工作方式,且其占它比的低两位DC1B1与DC1B0为11
INTCON=0X00; //禁止总中断和外围中断
PR2=150; //设置PWM的工作周期,也即PWM的工作频率 其中PWM周期=(PR2+1)*4*Tosc*TMR2预分频比,Tosc为MCU的振荡周期
//以当前程序为例,则PWM的输出频为 1/{(156+1)*4*0.25us(4M晶体)*1}=6.3694267515923566878980891719745k
TRISC=RC2=0; //设置CCP1引脚为输出方式
}
//A/D转化初始化子程序
void adinitial_voltage(void)
{
unsigned char a=50;
ad_data=0;
for(a;a--;)
{
ADCON0=0B01000001; //A/D 转换器模块工作;但AD转换不进行;FOSC/8
ADCON1=0B11100000; //ADRESH 寄存器的高6 位读为0;6位与7位须置1
ADIF=0; //AD转换中断标志先清出。
while(ADGO);
adresult.adre[0]=ADRESL;
adresult.adre[1]=ADRESH; //读取并存储A/D转换结果
ad_data+=adresult.y1;
ADGO=1;
}
ad_data/=50;
}
void display_voltage(void) //电压显示函数
{
int bai,shi,ge,qian,temp,change; //定义6个临时变量
temp=ad_data/208.97959183673469387755102040816*1000; //10位AD=1024,我的电源电压为4.9V,所心1024/4.9=208.9=209
TONOFF=(ad_data/208.97959183673469387755102040816)*25.000;
change=temp;
qian=temp/1000; //求显示的千位
bai=temp%1000/100; //求显示的百位
shi=(temp%100)/10; //求显示的十位
ge=temp%10; //求显示的个位
change=TABLE[qian]&0x7f; //显示一个小数点
PORTD=change;
PORTA=0B1111011; //RA2输出低电平,点亮千位显示
delay(1);
PORTD=TABLE[bai]; //查表得百位显示的代码
PORTA=0x37; //RA3输出低电平,点亮百位显示
delay(1); //延时一定时间,保证显示亮度
PORTD=TABLE[shi]; //查表得十位显示的代码
PORTA=0x2F; //RA4输出低电平,点亮十位显示
delay(1); //延时一定时间,保证亮度
PORTD=TABLE[ge]; //求个位显示的代码
PORTA=0x1F; //RA5输出低电平,点亮个位显示
delay(1); //延时一定时间,保证亮度
PORTD=0xff;
}
void ini(void)
{
TRISA=0B00000001;
TRISD=0;
PORTD=0XFF;
}
//延时子程序
void delay(unsigned char x) //延时程序
{
unsigned char i,i=x; //定义整形变量
for(i=250;--i;); //延时
}
void interrupt clkint(void) //定时器中断函数
{
QC++; //在这个函数中没有写TMRO=多少,主要目的是让TMR0自由的溢出,这样计时更准确。
T0IF=0x0;
}
本文档为【简单的PWM程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。