看到PIC单片机就感到亲切,今天开始对PIC16lf1936编程仿真,仿真器PICKIT3。
Mplab IDE的使用
一、接入PICkit3出现Target Device ID (00000000) does not match expected Device ID (00002460).
这是仿真头与线路板连接不正确。
二、首次使用pickit3出现:
PK3Err0040: The target device is not ready for debugging.Please check your configuration bit settings and program the device before proceeding.
解决办法:在这里勾 选:Debugger>Settings>Program Memory>Automatically 的 “Program after successful build”项即可在每次成功后自动下载代码到Flash并进入调试就绪模式。
三、接入PICkit3烧录时要设置电源
PK3Err0045: You must connect to a target device to use PICkit3.
Programmer>Settings>Power中设置
四、maplab的输出窗口看不见
1、在设置这个功能的时候,准备把output窗口移到下边缘,没想到移动过头,移动到电脑桌面的最下方(移到下发看不到的位置去了),然后output窗口就不见了,调不出来,在view里面勾选了output或者取消,编译文件,甚至重新启动电脑,output窗口都不出现了!
右击任务栏->解除锁定任务栏->拖动任务栏到右边就可以看到被隐藏的窗口了
2、隐藏在整个窗口的下方、
右侧是有进度条的
将output移上去,右侧就没有进度条了
Mplab X IDE的使用
图1 驱动切换与安装
图2 批量烧录
一、接入PICkit3提示找不到工具,为驱动没有安装
打开如图1 MPLAB drive,如下图设置,点"Apply Changes"即可。
二、microchip官网下载XC8编译器
实践
一、端口控制
完成三件事:
1、仿真部分全部正常;
2、配置字设置无误;
3、内部晶振正常,端口操作正常
#include "pic.h"
用尖括号:一般用于包含标准的库头文件,编译器会去系统配置的库环境变量和者用户配置的路径去搜索,而不会在项目的当前目录去查找;用双引号:一般用于包含用户自己编写的头文件,编译器会先在项目的当前目录查找,找不到后才会去系统配置的库环境变量和用户配置的路径去搜索
void delay_long(unsigned int uiDelayLong);
void main()
{
OSCCON = 0xeb; //禁止4X PLL,内部4MHz时钟源
TRISBbits.TRISB3 = 0; //设置RB5端口为输出
TRISCbits.TRISC4 = 0;
ANSELBbits.ANSB3 = 0; //RB5设置为数字端口
LATBbits.LATB3 = 0; //RB3输出低电平
LATCbits.LATC4 = 0;
WPUBbits.WPUB5 = 1;
while (1)
{
LATBbits.LATB3 = 1;
LATCbits.LATC4 = 0;
delay_long(100);
LATBbits.LATB3 = 0;
LATCbits.LATC4 = 1;
delay_long(100);
}
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<</font>uiDelayLong;i++) //
{
for(j=0;j<500;j++) //内嵌循环的空指令数量
{
;
}
}
}
/////////////////////////////////////////////////////////////////////////////
二、实现触摸功能
#include "pic.h"
__CONFIG(0x09E4);
__CONFIG(0x0033);
#define BackLight LATCbits.LATC4
#define Light1 LATAbits.LATA7
#define Light2 LATBbits.LATB3
#define Light3 LATAbits.LATA4
#define Light4 LATBbits.LATB4
#define L2_C LATCbits.LATC0
#define L1_C LATCbits.LATC1
#define C_R LATCbits.LATC2
#define C_L LATCbits.LATC3
#define Cap_H_L LATAbits.LATA6
#define const_key_time2 8
#define const_timr0_value 100
#define trip_value 150 //(未触摸值-触摸值)*80%
#define Cap_Avg_value 1500
void key_service(void);
void delay_long(unsigned int uiDelayLong);
static void interrupt SystemISR(void);
void System_Init(void);
void Cap_Init(void);
void SetNextSensor(void);
void RestartTimers(void);
void Cap_ISR(void);
unsigned char Index = 1; // 触摸键通道计数
unsigned char AvgIndex = 0; //更新频率计数
unsigned int Cap_Value = 0; //当前按键频率值
const unsigned int trip[4]={trip_value,trip_value,trip_value,trip_value}; //频率差值
unsigned int Cap_Avg[4]={Cap_Avg_value,Cap_Avg_value,Cap_Avg_value,Cap_Avg_value}; //频率平均值
unsigned int uiKeyTimeCnt1=0;
unsigned int uiKeyTimeCnt2=0;
unsigned int uiKeyTimeCnt3=0;
unsigned int uiKeyTimeCnt4=0;
unsigned char ucKeyLock1=0;
unsigned char ucKeyLock2=0;
unsigned char ucKeyLock3=0;
unsigned char ucKeyLock4=0;
unsigned char ucKey1TouchCnt=0;
unsigned char ucKey2TouchCnt=0;
unsigned char ucKey3TouchCnt=0;
unsigned char ucKey4TouchCnt=0;
unsigned char ucKeySec=0;
void main()
{
System_Init();
delay_long(10);
Cap_Init();
GIE = 1;
while (1)
{
key_service();
}
}
void key_service(void)
{
switch(ucKeySec)
{
case 1:
{
}
break;
case 2:
{
if(ucKey2TouchCnt == 1)
{
Light2 = 0;
C_L = 1;
}else
{
Light2 = 1;
C_L = 0;
ucKey2TouchCnt = 0;
}
}
break;
case 3:
{
}
break;
case 4:
{
}
break;
default:
break;
}
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i,j;
for(i=0;i<</font>uiDelayLong;i++) //
{
for(j=0;j<500;j++)
{
asm("nop");
}
}
}
void System_Init(void)
{
OSCCON = 0b01101000; //内部4M晶振
OSCTUNE= 0b00000000; //晶振校准
TRISCbits.TRISC0 = 0;
TRISCbits.TRISC1 = 0;
TRISCbits.TRISC2 = 0;
TRISCbits.TRISC3 = 0;
L2_C = 0;
L1_C = 0;
C_R = 0;
C_L = 0;
TRISAbits.TRISA6 = 0;
LATAbits.LATA6 = 0;
TRISCbits.TRISC4 = 0; //BackLight输出
TRISAbits.TRISA7 = 0; //Light1输出
TRISBbits.TRISB3 = 0; //Light2输出
TRISAbits.TRISA4 = 0; //Light3输出
TRISBbits.TRISB4 = 0; //Light4输出
TRISBbits.TRISB1 = 1; //RB1触摸按键输入
ANSELBbits.ANSB1 = 1; //RB1设置为模拟端口
WPUB = 0x00; //PORTB口无上拉
IOCBP = 0x00; //关PORTB口电平变化中断
IOCBN = 0x00;
BackLight = 0; //背景灯打开
Light1 = 1; //其它灯关闭
Light2 = 1;
Light3 = 1;
Light4 = 1;
}
void Cap_Init(void)
{
CPSCON0 = 0b10001100; //打开电容模块,高频率振荡
CPSCON1 = 0b00000001; //设置扫描通道0-3
OPTION_REG = 0b11010011; //TMR0 分频器1:16
TMR0IF = 0;
TMR0IE = 1;
T1CON = 0b11000101; //计数,时钟来源电容模块1:1分频
T1GCON = 0b00000000; //与门控位无关
TMR1GIF = 0;
TMR1GIE = 0;
TMR1H = 0;
TMR1L = 0;
TMR0 = const_timr0_value;
}
void SetNextSensor(void)
{
if(Index == 3)
{
Index = 0; //Key1-Key4
}
else
{
Index++;
}
CPSCON1 = Index;
}
void RestartTimers(void)
{
TMR1ON = 0;
TMR1H = 0;
TMR1L = 0;
TMR1ON = 1;
}
void Cap_ISR(void) //触摸按键扫描
{
if (Cap_Value < (Cap_Avg[Index] - trip[Index])) //有键按下,不更新频率平均值
{
switch(Index)
{
case 0: //KEY1 ON
{
}
break;
case 1: //KEY2 ON
{
if(ucKeyLock2==0)
{
uiKeyTimeCnt2++; //累加定时中断次数
if(uiKeyTimeCnt2>const_key_time2)
{
uiKeyTimeCnt2 = 0;
ucKeyLock2 = 1; //自锁按键置位,避免一直触发
ucKeySec = 2; //触发2号键
ucKey2TouchCnt++;
}
}
}
break;
case 2: //KEY3 ON
{
}
break;
case 3: //KEY4 ON
{
}
break;
default:
break;
}
}
else if (Cap_Value > (Cap_Avg[Index] - trip[Index] +64)) //无键按下,慢更新频率平均值64
{
switch(Index)
{
case 0: //KEY1 OFF
{
}
break;
case 1: //KEY2 OFF
{
ucKeyLock2=0; //按键自锁标志清零
uiKeyTimeCnt2=0;//按键去抖动延时计数器清零
}
break;
case 2: //KEY3 OFF
{
}
break;
case 3: //KEY4 OFF
{
}
break;
default:
break;
}
if (AvgIndex < 4)
{
AvgIndex ++; //更新频率
}
else
{
AvgIndex = 0;
}
if (AvgIndex == 4)
{
if(Cap_Value >= Cap_Avg[Index])
{
Cap_Avg[Index] = Cap_Avg[Index]+(Cap_Value - Cap_Avg[Index])/16;
}
else
{
Cap_Avg[Index] = Cap_Avg[Index]-(Cap_Avg[Index] - Cap_Value)/16;
}
}
}
}
static void interrupt SystemISR(void) //Timer0中断2.5ms
{
if(TMR0IE && TMR0IF)
{
TMR0IF = 0;
TMR0 = const_timr0_value;
TMR1ON = 0; //停止触摸按键振荡频率计数
Cap_Value = (unsigned int)(TMR1H <<8) + TMR1L; //读取振荡频率
Cap_ISR();
//SetNextSensor(); //设置通道
RestartTimers(); //重启TMR1
}
if (TMR0IE && TMR0IF)
{
TMR0IF = 0;
RestartTimers();
}
}
///////////////////////////////////////////////////////////////////////////
三、 使用PIC公司的触摸库做触摸处理
采用PIC公司提供的库,到http://www.microchip.com/mla,可以下载,另外要注意MPLAB_IDE_8_76版本IDE,C编译器用picc-9_81-win.exe。
这就是PIC公司的触摸库,装好后得到的是一系列触摸MCU的demo,找到我们要的库(含有PIC16F1827),然后我们把它拷贝出来,对它进行配置和改造。Configure-->Select Device选择PIC16F1827,整个程序默认的速度是片内晶振16M,
①配置generic_processorConfigBits.h,实现对用内部晶振等等。
还需要修改的地方:mTouch_config.h中修改两个地方:
②这个是修改通道。
③修改触摸灵敏度,值越小灵敏度越大。
④在主函数main.c中读出触摸值,这里的CAP_DATA值大概是1或2。
使用PIC公司的触摸库做触摸处理,得到的效果非常好。
C与汇编混合编程
#include "pic.h"
unsigned char add_function(unsigned char augend,unsigned char addend);
volatile unsigned char tmp; //定义位于bank0 的字符型全局变量
void main(void)
{
unsigned char temp1,temp2,temp3;
temp3=add_function(2,3);
asm("clrwdt"); //清看门狗
OSCCON = 0xeb; //禁止4X PLL,内部4MHz时钟源
TRISBbits.TRISB3 = 0; //设置RB5端口为输出
TRISCbits.TRISC4 = 0;
ANSELBbits.ANSB3 = 0; //RB5设置为数字端口
LATBbits.LATB3 = 0; //RB3输出低电平
LATCbits.LATC4 = 0;
WPUBbits.WPUB5 = 1;
_asm
CLRF _STATUS //选择bank0
MOVLW 0x10 //设定初值
MOVWF _tmp //tmp=0x10
_endasm
if (tmp==0x10)
{
_nop();
}
}
unsigned char add_function(unsigned char augend,unsigned char addend)
{
return(augend+addend);
}