PIC16lf1936编程仿真及PIC触摸库

看到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);
}

 

 

永不止步步 发表于12-21 13:49 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67410个|学分:305367个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号