|
軟件開(kāi)發(fā)環(huán)境:Keil5,STC-ISP。
硬件環(huán)境:自己畫(huà)的板子,兩個(gè)外部中斷都沒(méi)有加外部上拉電阻(用的是STC內(nèi)部的上拉電阻),I2C有外部上拉(STC的I2C管腳設(shè)為開(kāi)漏)
我在試驗(yàn)使用一個(gè)旋轉(zhuǎn)編碼器控制OLED屏幕的顯示內(nèi)容,功能分為兩個(gè):1. 旋轉(zhuǎn)編碼器使用外部中斷進(jìn)行檢測(cè)。
2. OLED屏用I2C中斷通信。
我先把兩個(gè)功能分別做好測(cè)試好了,但是組合在一起以后外部中斷就完全無(wú)法響應(yīng)(或者說(shuō)一直被觸發(fā)但沒(méi)有執(zhí)行,原因我貼在后面的代碼里),I2C和UART功能正常。
想說(shuō)用硬件仿真,結(jié)果每次仿真跑到:【P_SW2|=0x80; //訪問(wèn)擴(kuò)展寄存器Enable】 的時(shí)候仿真就斷了。實(shí)在無(wú)語(yǔ)。。。
然后嘗試調(diào)整中斷優(yōu)先級(jí),把外部中斷優(yōu)先級(jí)設(shè)為3(最高),I2C設(shè)為0(最低),結(jié)果沒(méi)有變化,還是不行。
最后的解決方法是把I2C中斷關(guān)閉,設(shè)置為詢問(wèn)式;把UART中斷關(guān)閉,設(shè)為詢問(wèn)式,也就是只有外部中斷,其他中斷都禁止了。然后外部中斷才能正常響應(yīng)。
PS: 有人說(shuō)你直接用例程拼起來(lái)就行啦,實(shí)際是官方的I2C例程有點(diǎn)問(wèn)題,并不能正常運(yùn)行。所以自己重新寫(xiě)了一個(gè)。
功能雖然勉強(qiáng)實(shí)現(xiàn)了,但問(wèn)題始終沒(méi)有解決,請(qǐng)有經(jīng)驗(yàn)的大神指教指教,謝謝!
單片機(jī)代碼:
#include "STC8xxxx.h"
#include "config.h"
#include "STC8H_I2C.h"
#include "STC8H1K08ExINT.h"
#include "SSD1315.h"
#define PinB P12
void Delay10us(void)
{
unsigned char i;
_nop_();
i = 155;//15
while (--i) _nop_();
}
void Delay1000ms() //@22.1184MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 85;
j = 12;
k = 155;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
unsigned char Int0=0,Int1=0;
//================================================================================//
/**********************************************************************************/
//================================================================================//
void main(){
unsigned char n=0,k=0,l=0,j=0,z=0;
char i=1;
P_SW2|=0x80;
EA=1;
i2c_init();
i2c_pin_config(P14_P15);
INT_PinConfig(1,1);//set IN0/IN1 PIN PullUP
set_INT1_falling_edge;
set_INT0_falling_edge;
Dis_INT0;
Dis_INT1;
P1M0|=0x08;// set P13 Beeper push/pull output, P12 High R input.
P1M1|=0x04;// set P13 Beeper push/pull output, P12 High R input.
P1PU|=0x04;// set P12 Pullup Resister enable.
OLED_ini();
OLED_Clear();
Set_INT0_Priority(3);
Set_INT1_Priority(3);
while(1){
En_INT0;
En_INT1;
TX1_write2buff(TCON); //之前說(shuō)外部中斷一直被觸發(fā)但沒(méi)有執(zhí)行,原因就在這里,我打印 TCON 寄存器的值,得到的都是0xFF,也就是外部觸發(fā)標(biāo)志位一直置位,就算手動(dòng)清零也清不掉(試過(guò),沒(méi)用就把代碼刪了)。不用I2C中斷之后,TCON寄存器的值就正常了,該響應(yīng)響應(yīng)。
if(Int1){ //Detect Encoder spining direction
Dis_INT1;
if(k){
if(PinB) l++;
}
Int1=0;
k++;
En_INT1;
}
if(k==2){
Dis_INT1;
if(l){
i--;
if(i<1){
i=8;
}
}
else{
i++;
if(i>8){
i=1;
}
}
OLED_Clear();
for(n=0;n<128;n++){
OLED_Set_Pos(n,i-1);
OLED_WR_Byte(0x01,Data);
write_img_flash(n,i-1,0x01);
}
Int1=0;
k=0;
l=0;
En_INT1;
}
if(Int0){
int x=10,y=7;
Dis_INT0;
write_word(1,1,0,0);
Combine_img(0,32,32,x,y,IMG_and);
Write_change_data(x,y,x+32,y+32);
Int0=0;
En_INT0;
}
}
}
void INT1_Service() interrupt 2 {
Int1=1;
}
void INT0_Service() interrupt 0 {
Int0=1;
}
//--------------------- STC8H1K08ExINT.H:-------------------//
#ifndef _STC8H1K08ExINT_H_
#define _STC8H1K08ExINT_H_
#define En_INT IE|=0x80; //Set IE bit.7 EA to 1, GlobalInterupt Control Enable.
#define Dis_INT IE&=~0x80; //Set IE bit.7 EA to 0, GlobalInterupt Control Disable.
#define En_INT1 IE|=0x04 //Set IE bit.2 EX1 to 1, External Interupt 1 Enable.
#define Dis_INT1 IE&=~0x04 //Set IE bit.2 EX1 to 0, External Interupt 1 Disable.
#define En_INT0 IE|=0x01 //Set IE bit.0 EX0 to 1, External Interupt 1 Enable.
#define Dis_INT0 IE&=~0x01 //Set IE bit.0 EX0 to 0, External Interupt 1 Disable.
#define set_INT1_rising_and_falling_edge TCON&= ~0x04 //Set TCON bit.2 to 0, INT1 rising&falling edge detect.
#define set_INT1_falling_edge TCON|=0x04 //Set TCON bit.2 to 1, falling edge detect.
#define set_INT0_rising_and_falling_edge TCON&= ~0x01 //Set TCON bit.0 to 0, INT0 rising&falling edge detect.
#define set_INT0_falling_edge TCON|=0x01 //Set TCON bit.0 to 1, INT0 falling edge detect.
void INT_PinConfig(unsigned char ,unsigned char );//set IN0/IN1 PIN PullUP
void Set_INT0_Priority(unsigned char );
void Set_INT1_Priority(unsigned char );
#endif
//--------------------- STC8H1K08ExINT.c:-------------------//
#include "STC8xxxx.h"
#include "STC8H1K08ExINT.h"
void INT_PinConfig(unsigned char IN0,unsigned char IN1)//set IN0/IN1 PIN State
{
if(IN0) {
P3PU|=0x04; //set P3PU bit.2 to 1, Interal PullUP R Enable.
P3M0&=~0x04; //set P3M0 bit.2 to 0, High R Input.
P3M1|=0x04; //set P3M1 bit.2 to 1, High R Input.
}
else{
P3PU&=~0x04; //set P3PU bit.2 to 0, Interal PullUP R Disable.
P3M0&=~0x04; //set P3M0 bit.2 to 0.
P3M1&=~0x04; //set P3M1 bit.2 to 0.
}
if(IN1) {
P3PU|=0x08; //set P3PU bit.3 to 1, Interal PullUP R Enable.
P3M0&=~0x08; //set P3M0 bit.3 to 0, High R Input.
P3M1|=0x08; //set P3M1 bit.3 to 1, High R Input.
}
else{
P3PU&=~0x08; //set P3PU bit.3 to 0, Interal PullUP R Disable.
P3M0&=~0x08; //set P3M0 bit.3 to 0.
P3M1&=~0x08; //set P3M1 bit.3 to 0.
}
}
void Set_INT0_Priority(unsigned char pr){
switch(pr){
case 0:IP&=~0x01;IPH&=~0x01;
case 1:IP|=0x01;IPH&=~0x01;
case 2:IP&=~0x01;IPH|=0x01;
case 3:IP|=0x01;IPH|=0x01;
}
}
void Set_INT1_Priority(unsigned char pr){
switch(pr){
case 0:IP&=~0x04;IPH&=~0x04;
case 1:IP|=0x04;IPH&=~0x04;
case 2:IP&=~0x04;IPH|=0x04;
case 3:IP|=0x04;IPH|=0x04;
}
}
//--------------------- STC8H_I2C.H:-------------------//
#ifndef _STC8H_I2C_H_
#define _STC8H_I2C_H_
#define P14_P15 1
#define P33_P32 4
void i2c_init(void);
void Wait(void);
void i2c_start(void);
void i2c_stop(void);
void Set_I2C_INT_Priority(unsigned char);
void i2c_pin_config(unsigned char );
#endif
//--------------------- STC8H_I2C.C:-------------------//
#include "STC8xxxx.h"
void i2c_init(void){
P_SW2 |=0x80;
IE|=0x80;
//最高400kHz
I2CCFG|=0xCD;//D8
I2CMSCR|=0x00;
I2CMSAUX|=0x01;
I2CMSST=0x00;
}
void i2c_pin_config(unsigned char pin){
switch(pin){
case 1: P1M1|=0x30; P1M0|=0x30; //P14,P15 Open Drain
case 4: P3M1|=0x0C; P3M0|=0x0C; //P33,P32 Open Drain
}
}
void Wait(){
P_SW2 |= 0x80;
while (!(I2CMSST & 0x40));
I2CMSST &= ~0x40;
}
void i2c_start(void){
I2CMSCR=0X01;
Wait();
}
void i2c_stop(void){
I2CMSCR=0X06;
Wait();
}
void Set_I2C_INT_Priority(unsigned char pr){
switch(pr){
case 0:IP2&=~0x40;IP2H&=~0x40;
case 1:IP2|=0x40;IP2H&=~0x40;
case 2:IP2&=~0x40;IP2H|=0x40;
case 3:IP2|=0x40;IP2H|=0x40;
}
}
|
|