请教一个问题。鄙人有个pic12f675的程序。在proteus可以运行。烧入片子不能运行,求解

2020-02-09 11:28发布

程序在此:
#include<pic.h>
//12F675
//*****************

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & BOREN & PROTECT & CPD);
//__CONFIG(INTIO & WDTEN & PWRTEN & MCLRDIS & BOREN & PROTECT & CPD);

//内部RC振荡器普通IO口;无效看门狗;上电延时;内部复位;掉电复位;代码保护;数据保护

#define PWM                 GPIO5
#define PWM_DIR                TRIS5
#define AD_CH1                GPIO0
#define ON                        1
#define OFF                        0
/////////////////////////////////////
//变量定义
volatile unsigned char out_pwm;
unsigned char input_ad;
unsigned char index=0;                        //用于周波控制的计数器


unsigned char index_len1 =100;        //波形前段输出波形的周期.
unsigned char index_len2 =100;        //波形后段输出波形的周期.

unsigned char index_on1;                //波形前段的开 周波数         
unsigned char index_off1;                //波形前段的关 周波数
unsigned char state1_cnt;                //波形前段的重复次数
unsigned char index_on2;                //波形后段的开周波数       
unsigned char index_off2;                //波形后段的关周波数
unsigned char stage=0;                        //波形所处的阶段
////////////////////////////////////
// 定义0%-100%的波形数据数组.
// 先是开的波数,再是关的波数,然后又是开的波数,再是关的波数.以255为数据结束标记.


const unsigned char  wave[51][5] =
{
        //表格指定规则,开波数目和总波数(100),能约分先约分
        //产生约分后的新的纵波束和开波数目
        //将(总的波数)/(开波数)=重复次数...最后一次关波数
        //为了方便列举各种情况,最后一次的开关波数均允许调整,
        //因此重复次数要减1。
        // 相当于(总的波数)/(开波数)有余数存在时,可将重复次数减1,将最后一个开关波,
        // 当作个例来处理,如果没有余数存在则重复一次就可以了.最后一个开关波数均为0
        // 51%-100%控制,可以将参考0-50的做法.将被控波改为关波数,
        // 同时,关波数的数码就是(100-开波数)
       
        0,2        ,1,0,2,         //0:0-开波数,-2关波数-0次数,-最后一次的开关波数均为0
        1,99,1,1,99,        //1:1-开波数,-99关波数-次数1,-最后一次的开关波数均为0无需处理
        1,49,1,1,49,        //2:1on, 49off,1次,
        1,32,2,1,33,//3:1on, on1off32 ,2times=66,再on1off33,共100
        1,24,1,1,24,  //4:1on, 24off,1times,last count 24,
        1,19,1,1,19, //5
        1,15,2,1,17,//6/100: 3/50相当于on1off15,2次共32波,加上on1off17,共50
        1,13,6,1,15,//7/100: on1off13 6times共84,加上on1off15,共100波
        1,11,1,1,12,//8/100=2/25  
        1,10,8,1,11,//9/100,
        1,9        ,1,1,9,        //10/100= 1/10 on1off9, 1times
       
        1,8,10,1,9,        //11/100 相当于:开1-关8,共10次再开1关9一次
    1,7,2,1        ,8,        //12/100=3/25;  开1关7共3次,最后一次多关1,为8
        1,7,12,1,3,        //13/100 ,开1关7,共12次,共96波 在开1关3,共计100
        1,6,6,1,7,        //14/100=7/50, 开1,关6,共6次,共42波,再开1关7,共计50
        1,5,2,1,7,        //15/100=3/20; on1off5 2times,再开1guan7.共20
        1,5,3,1,6,        //16/100=4/25,on1off5 ,3times, 再开1关6共25
        1,5,16,1,3,        //17/100on1off5,16times,再开1关3,共100
        1,5,8,1,1,        //18/100=9/50, on1off5,8times,再on1off1共50次
        2,8,9,1,9,        //19/100,on2off8, 9times,再on1off9,共100个波,开波数为2x9+1=19
        1,4,1,1,4,   //20/100=1/5, on1off4 1times,

       
        1,4,19,        2,3,        //21/100 on2off8, 9times,再on3off7,共100个波,开波数为2x9+3=21
    1,4,9,        2,3,        //22/100=11/50;  on1off4, 9times,then on2off3,total50,on times=1x9+2
        1,4,19,        4,1,        //23/100 ,on2off8, 9times,再on5off5,共100个波,开波数为2x9+5=23
        1,3,5,        1,4,        //24/100=6/25,  
        1,3,1,        1,3,        //25/100=1/4;
        1,3,12,        1,1,        //26/100=13/50, on1off 3,12times,then on1off1,total 48+2=50
        2,5,13,        1,8,        //27/100  on2off5 ,13time,=91+1+8=100,on times 2x13+1=27
        1,3,6,        1,0,        //28/100=7/25,
        2,5,14,        1,1,        //29/100,
        1,2,2,        1,3,   //30/100=3/10, on1off2, 2times,then on1off3.total 10

       
        1,2,30,        1,9,        //31/100  
    1,2,7,        1,3,        //32/100=8/25;
        1,2,32,        1,3,        //33/100 ,
        1,2,16,        1,1,        //34/100=17/50,  
        1,2,6,        1,1,        //35/100=7/20;
        1,2,8,        1,0,        //36/100=9/25,
        1,2,31,        6,1,        //37/100        
        1,2,15,        4,1,        //38/100=19/50,
        1,2,30,        9,1,        //39/100,
        1,1,1,        1,2,   //40/100=2/5,  
       
       
        2,3,19,        3,2,        //41/100  
    1,1,20,        1,9,        //42/100=21/50;
        2,3,19,        5,0,        //43/100 ,
        1,1,10,        1,4,        //44/100=11/25,  
        1,1,8,        1,3,        //45/100=9/20;
        1,1,22,        1,5,        //46/100=23/50,
        1,1,46,        1,7,        //47/100        
        1,1,11,        1,2,        //48/100=12/25,
        1,2,30,        9,1,        //49/100,
        1,1,1,        1,1,   //50/100=1/2,  
       

       
};




/////////////////////////////////////
// 函数声明
unsigned char ad_rd_filtered( void );
unsigned char ad_rd( void );
void interrupt zd(void);        //中断函数

unsigned char get_pwm( unsigned char in_ad );
void  delay_us( unsigned char n );
void pwm( unsigned char cmd );//操作pwm输出
//主函数***************************************************
void main( void )
{

        TRISIO=0b11111111;        //初始化IO端口
        PWM_DIR        = 0;                //PWM所在引脚设置为输出
        PWM =0 ;

        delay_us(200);
       
        CMCON=7;                //不使用比较仪,即IO口为普通数字端口
        ADCON0=0B00000001;
//*******************
//bit7--0:左移AD转换结果,使用10位结果中的高8位
//bit6--0:参考电压选用VDD
//bit5--0:无效
//bit4--0:无效
//bit3--0:两位共同表示AD转换的通道
//bit2--0:/本例选择通道0
//bit1--0:设定此位开始转换,转换完成硬件清0
//bit0--1:允许AD转换的总开关
//*******************
ANSEL=0B00010001;
//*******************
//bit7--0:无效
//bit6--0:
//bit5--0: >AD转换时钟选择位,本例选择"系统时钟/8"
//bit4--1:/
//bit3--0:
//bit2--0: IO引脚功能选择端,为1时作为模拟输入端,
//bit1--0: /为0时作为数字引脚
//bit0--1:/ 选择AD0作为输入
//*******************
OPTION=0B00000111;
//*******************
//bit7--0:无效
//bit6--0:
//bit5--0: >AD转换时钟选择位,本例选择"系统时钟/8"
//bit4--1:/
//bit3--0:  PSA=0;将分频比分配给tmr0
//bit2--0:
//bit1--0:  设置tmr0的分频比为1/256
//bit0--1:/
//*******************
       
        //T0IF=0;                //清除TMR0中断标志位
        GIE=1;                        //使能全局中断
        //T0IE=1;                //全能TMR0中断
        /////////////////T1初始化
        T1CON =0x00;//设置时钟为Fosc/4 分频比为1

        TMR1IF = 0;//清楚t1中断标志
        TMR1IE =1;//t1中断允许
        PEIE =1;  //允许外设中断
        TMR1L = (65535 - 20000)%256;//加载初值, 20ms       
        TMR1H = (65535 - 20000)/256;//加载初值, 20ms
                TMR1ON=1;//启动time1
       
         while(1)
        {
                asm("clrwdt");//喂狗
       
         }
}

//中断函数*************************************************
void interrupt zd(void)
{
       
       
        if( TMR1IF == 1 )
        {       
                TMR1IF = 0;
                TMR1ON=0;//关闭定时器1
                //////////////////////////////////////////////
                //=========1 波形的初始化处理,读取波形表
                if( stage == 0)
                {
                        input_ad         =         ad_rd_filtered();                //读取电压值
                        out_pwm           =        get_pwm(input_ad);        //计算输出的占空比

                        index =0;
                                if(out_pwm<=50)
                                {
                                        index_on1=wave[out_pwm][0];  //波形开
                                        index_off1=wave[out_pwm][1]; //波形关
                                         state1_cnt=wave[out_pwm][2];//读取重复次数
                                        index_len1         =   wave[out_pwm][1]+wave[out_pwm][0];       
                                                                        //读取周期表中的周期(总的周波数)               
                                        index_len2         =   wave[out_pwm][3]+wave[out_pwm][4];       
                                                                        //读取周期表中的周期(总的周波数)                       


                               
                                        index_on2 =wave[out_pwm][3]; //尾部波形-开
                                        index_off2=wave[out_pwm][4]; //尾部波形 关       
                                }
                                else//50以上.将pwm电平取反.当作50以下的情况处理
                                {

                                        index_on1=wave[100-out_pwm][0];  //波形开
                                        index_off1=wave[100-out_pwm][1]; //波形关
                                        state1_cnt=wave[100-out_pwm][2];//读取重复次数
                                         index_len1         =   wave[100-out_pwm][1]+wave[100-out_pwm][0];       
                                                                        //读取周期表中的周期(总的周波数)               
                                        index_len2         =   wave[100-out_pwm][3]+wave[100-out_pwm][4];       
                                                                        //读取周期表中的周期(总的周波数)                       


                               
                                        index_on2 =wave[100-out_pwm][3]; //尾部波形-开
                                        index_off2=wave[100-out_pwm][4]; //尾部波形 关                                       
                                }
                                                        //////////////////////////////////////
                                //波形开始时
                                if( index == 0 )
                                {                        //////////////////////////////////////////////////////
       
                                        if(out_pwm == 0)
                                        {
                                                pwm(OFF);
                                        }
                                        else
                                        {
                                                pwm(ON);
                                        }
                                }
                                stage =1;        //状态递进
                                index =1;

                }
                //end =========1 波形的初始化处理,读取波形表
               
               
                ////////////////////////////////////////////////////////////////////////////
                //=========2 波形的前面段处理
                /////////////////////////////////////////////////////////////////////////////
                else if( stage ==1 )
                {

                       
                                /////////////波形由开到关
                                 if(index ==index_on1 )
                                {
                                                pwm(OFF);
                                }
                /////////////////////////////////////////////////周期重新开始处理
                               
                                else if( index == index_len1 )
                                {
                                        index = 0;//归零,准备下一个周期
                                        state1_cnt --;
                                        pwm(ON);
                                        if( state1_cnt ==0 )//前段波形循环结束
                                        {
                                              stage =2;
                                        }
                                       
                                               
                                }

                                index++;          
                 }
                                    

                ////////////////////////////////////////////////////////////////////////////
                //end =========2 波形的前面段处理
                /////////////////////////////////////////////////////////////////////////////
               
                /////////////////////////////////////////////////////////////////////////
                //=========3 波形的后段处理
                ////////////////////////////////////////////////////////////////////////
          else if( stage ==2 )
                {
                        ///////////////////
                        //如果补充波形不为0
                        if(index_on2!=0)
                        {
                                if( index ==0 )
                                {
                                                pwm(ON);

                                }
                                else
                                if( index >= index_on2)       
                                {
                                        pwm(OFF);
                                }
                                /////////////////////////////////////
                                index ++;
                                ///////////////////////////////////完整的一个波形输出结束
                                if(  index== index_len2)
                                {
                                        index =0;
                                        stage =0;                                       
                                }
                         }       

                }       
                //////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////重新加载计数器初值
                TMR1L = (65535 - 20000)%256;//加载初值, 20ms       
                TMR1H = (65535 - 20000)/256;//加载初值, 20ms
                TMR1ON=1;//启动time1
               
        }

}


/* ad转换程序 */
unsigned char ad_rd( void )
{
        unsigned char ret=0;
       
        asm("nop");               
        asm("nop");               
        asm("nop");               
        asm("nop");
       
        GODONE =1 ;
       
        while(GODONE ==1);
       
        ret = ADRESH;
       
        return ret;

}

/* ad 滤波程序 */
unsigned char ad_rd_filtered( void )
{
        unsigned char cnt=0;       
        unsigned char ret=0;
       
        unsigned int total=0;
        for( cnt =0 ;cnt<4 ; cnt++ )
        {
                total =total+ ad_rd();       
        }
        total = total>>2;
        ret = (unsigned char)total;
        return ret;
}


/* 计算输出pwm百分比 */
unsigned char get_pwm( unsigned char in_ad )
{
        unsigned char ret;
        if( in_ad <= 51)//1v电压对应ad
        {
                ret = 0;    //pwm百分比为0
        }
        else
        if(  in_ad >51 &&  in_ad <255 )
        {
                ret =  ((unsigned int)(in_ad-51) *(unsigned int)100)/(unsigned int)(255- 51);
        }
        else
        {
                ret =100;
        }
        return ret;

}

void delay_us( unsigned char n )
{
        while( n--  )
        {
                asm("nop");               
                asm("nop");               
                asm("nop");               
                asm("nop");
        }
}
void pwm( unsigned char cmd )
{
        if( cmd == ON )
        {
                if( out_pwm<=50 )
                {
                        PWM =1; //到了关周期,将输出置为0;
                }
                else
                {
                        PWM=0;
                }
        }
        else
        {
                if( out_pwm<=50 )
                {
                        PWM =0; //到了关周期,将输出置为0;
                }
                else
                {
                        PWM=1;
                }               
       
        }


}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
1条回答
xinxiaojun
1楼-- · 2020-02-09 13:11
程序的功能是在GPIO0输入一个1-5v的电压值,ad转换后,控制pwm,在GPIO5输出一个控制波。1v对应一定周期内通过的周波为0;
5v对应,一定周期内周波为100%,如以2s为周期 ,控制波形再去触发一个固态继电器,控制输出的220vac的周波数,
实现一个周波过零控制

(原文件名:11.JPG)

一周热门 更多>