搜索
bottom↓
回复: 5

pic12f675的程序,config正确配置,在proteus和mplab IDE中均可以正常仿真,烧入片子却无

[复制链接]

出0入0汤圆

发表于 2010-8-16 13:12:11 | 显示全部楼层 |阅读模式
各位pic高手,请支援。
程序在此:
#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;
}

}


}  



本贴被 xinxiaojun 编辑过,最后修改时间:2010-08-16,10:27:30.

出0入21汤圆

发表于 2010-8-16 13:46:35 | 显示全部楼层
搞个IO口放到主循环里取反用示波器观察或接一个LED,先看看你程序有没有在跑,如果没有在跑那可能你的时钟或复位配错了,也可能芯片坏了,如果在跑那就是你的程序有问题了,再把IO口放到一些关键的地方监测你程序的运行状况。

出0入0汤圆

 楼主| 发表于 2010-8-16 15:30:21 | 显示全部楼层
xiexie tks

出0入0汤圆

发表于 2014-3-26 20:25:45 | 显示全部楼层
看看,学习一下!

出0入0汤圆

发表于 2014-3-27 09:44:53 | 显示全部楼层
配置位很重要,其次就是软件仿真和实际动手实践的大区别了

出0入0汤圆

发表于 2014-11-10 20:58:18 | 显示全部楼层
1楼正解
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 04:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表