#include<pic.h>
//PIC16F876A
//-系统配置,选择高速晶振,上电延时复位,掉电复位使能,代码保护,打开看门狗
__CONFIG( HS & PWRTEN & BOREN & PROTECT & WDTEN );
//----------------------------------------------------------
bank1 unsigned char tm_sum;//系统实际变量
bank1 float sin_am, sin_l, sin_d;//浮点数,幅值变量,临时变量,临时变量
bit sin_up;//sin函数正负半周标志
bit b_timer_ok; //定时标志
const unsigned char PWM_TAB[]={
0,25,50,74,98,120,142,162,180,197,212,
225,235,244,250,254,255,254,250,244,235,
225,212,197,180,162,142,120,98,74,50,25
/*
40,50,73,85,100,113,127,141,157,170,180,189,196,200,203,
204,//正半周
204,//负半周
203,200,195,188,179,169,157,144,129,113,96,78,59,39,15
*/
};
unsigned char index;//SIN函数表查表变量
//软件延时子程序*/
void DELAY(void)
{
unsigned int i;
for(i=2000;i>0;i--) CLRWDT();
}
/*****************************************************************************************************
* 函数:port_init()
* 功能:IO初始化
* 输入:无
* 输出:无
*****************************************************************************************************/
void port_init(void)//端口初始化
{
//-端口b设置
/*
TRISB0 = 0x00; //RB端口方向设置,输出
PORTB = 0; //输出0
RBPU = 0; //使能内部弱上拉
INTE = 0; //禁止RB0中断
RBIF = 0;
// RBIE = 1; //允许RB端口电平变化中断
*/
//-端口c设置
TRISC = 0x00; //PORTC are outputs
PORTC = 0; //输出为0
/*
//-timer0 init
T0CS = 0; //选择内部指令时钟
T0IF = 0;
//T0IE=1; //在第一次ccp1比较后打开中断使能
//timer1
TMR1CS=0; //定时器模式
*/
}
/*****************************************************************************************************
* 函数:ISR_CCP()
* 功能:CCP初始化
* 输入:无
* 输出:无
*****************************************************************************************************/
void CCP_Init(void)
{
CCPR2L = 0X00; //设置CCP2,0%的脉宽输出
CCPR1L = 0X00; //设置CCP1,0%的脉宽输出
TRISC1 = 0;
TRISC2 = 0; //RC1,RC2输入模式
TRISC = 0X00; //PORTC are outputs
PR2 = 0XFF; //设置PWM的工作周期,16Mhz,PWM周期15.562khz
CCP1M3 = 1;
CCP1M2 = 1; //CCP1模块PWM模式
CCP2M3 = 1;
CCP2M2 = 1; //CCP2模块PWM模式
sin_up = 1; //正负半周SIN函数
index = 0; //脉宽周期调整计数器
sin_am = 1; //sin函数的幅值
}
/*****************************************************************************************************
* 函数:ISR_CCP()
* 功能:CCP中断
* 输入:无
* 输出:无
*****************************************************************************************************/
void ISR_CCP(void)
{
if(index == 31)
{
index = 0;
sin_up = !sin_up;
}
sin_l = sin_am * PWM_TAB[index];
if(sin_l >= 255)
sin_l = 255; //限幅
if( sin_up )
{
CCPR1L = 0;
CCPR2L = (unsigned char)sin_l;
}//换向
else
{
CCPR2L = 0;
CCPR1L = (unsigned char)sin_l;
}//换向
index++;
}
/*****************************************************************************************************
* 函数:isr_servers()
* 功能:中断服务程序
* 输入:无
* 输出:无
*****************************************************************************************************/
void interrupt isr_servers(void)
{
//--定时器2中断服务函数
if(TMR2IF & TMR2IE)
{
TMR2IF = 0;
ISR_CCP();
}
CLRWDT();//清除看门狗
/*
if(RBIF && RBIE)
{
RBIF=0;
if(!RB6)
k=1;
}//端口b中断服务函数
*/
//--定时器1中断服务函数
if(TMR1IF & TMR1IE)
{
TMR1IF = 0;
if( ++tm_sum >= 10 )
{
tm_sum = 0;
//b_timer_ok = 1;
RC3 = !RC3;
}
}
}
main(void)
{
OPTION = 0x0F;
CLRWDT(); //清除看门狗
port_init(); //端口初始化
PEIE = 1; //外围模块中断使能
GIE = 1; //开全局中断
TMR1CS = 0; //Fosc/4
T1SYNC = 0; //与外部时钟输入同步
TMR1H = 0xFD;
TMR1L = 0x10; //定时器1初值
TMR1IE = 1; //定时器1中断使能
TMR1ON = 1; //打开定时器1
TOUTPS3 = 0;
TOUTPS2 = 1;
TOUTPS1 = 0;
TOUTPS0 = 0; //定时器2后分频器5分频
TMR2IE = 1; //打开定时器2中断使能
TMR2ON = 1; //打开定时器2
CCP_Init(); //开始SPWM
while(1)
{
CLRWDT();
if( b_timer_ok )
{
b_timer_ok = 0;
// RC3 = !RC3;
}
}
}
PIC16F876A-SPWM.rar_ SPWM 50_50hz_SPWM EN PSP_pic16F876A正弦波_p
版权申诉
117 浏览量
2022-09-24
13:21:19
上传
评论
收藏 50KB RAR 举报
四散
- 粉丝: 51
- 资源: 1万+
评论0