STM8L152 _asm("rim");语句后程序卡住
最近正在使用12864液晶屏 打算用定时器和中断,但是主程序一运行到rim语句就会卡住,不知道这是怎么回事?TIM1和EXTI0的初始化设置都是按照以前单独可以用的例子来的下面贴出程序 不知道有没有大大能解答一下
#include"stm8l152r8.h"
#define uchar unsigned char
#define uint unsigned int
_Bool RW @PE_ODR:3;
_Bool RS @PE_ODR:4;
_Bool E @PE_ODR:5;
_Bool DB0 @PB_ODR:1;
_Bool DB1 @PB_ODR:2;
_Bool DB2 @PB_ODR:3;
_Bool DB3 @PB_ODR:4;
_Bool DB4 @PB_ODR:5;
_Bool DB5 @PB_ODR:6;
_Bool DB6 @PG_ODR:4;
_Bool DB7 @PG_ODR:5;
_Bool DB6I @PG_IDR:4;
_Bool DB7I @PG_IDR:5;
//_Bool UP @PD_IDR:5;
//_Bool DOWN @PD_IDR:6;
//_Bool LEFT @PD_IDR:7;
//_Bool RIGHT @PE_IDR:7;
_Bool EXTI0 @PB_IDR:0;
uchar num[]="0123456789";
uchar table[]="开始游戏";
uchar row,line,RAMDON,h;
/**********************初始化程序************************/
void CLK_init(void)
{
CLK_CKDIVR=0X00;//16M时钟不分频
}
void delay(uint i)
{
uint x,y;
for(x=0;x<i;x++)
for(y=0;y<160;y++);
}
void quickdelay(uint i)
{
uint x,y;
for(x=0;x<i;x++)
for(y=0;y<50;y++);
}
void GPIO_init(void)
{
PE_DDR |= 0X38;
PE_CR1 |= 0X38;
PE_CR2 &= 0XC7;//PE3PE4PE5推挽
PB_DDR &= 0XFE;
PB_CR1 |= 0X01;
PB_CR2 |= 0X01;//PB0外部中断上拉输入
PD_DDR &= 0X1F;
PD_CR1 |= 0XE0;
PD_CR2 |= 0XE0;
}
void DB_WR_init(void)
{
PB_DDR |= 0X7E;
PB_CR1 |= 0X7E;
PB_CR2 &= 0X81;
PG_DDR |= 0X30;
PG_CR1 |= 0X30;
PG_CR2 &= 0XCF;//DB0-7推挽输出
}
void DB_RD_init(void)
{
PB_DDR &= 0X81;
PB_CR1 |= 0X7E;
PB_CR2 &= 0X81;
PG_DDR &= 0XCF;
PG_CR1 |= 0X30;
PG_CR2 |= 0X30;//DB0-7上拉输入
}
void TIM1_init(void)
{
CLK_PCKENR2 |= 0x02;//使能TIM1外围时钟
TIM1_CR1=0X00;//向上计数,无预装载
TIM1_IER=0X01;//更新中断使能
TIM1_PSCRH=0X80;
TIM1_PSCRL=0X00;//32768分频
TIM1_ARRH=0X00;
TIM1_ARRL=0Xcc;//重装载值
TIM1_CR1|=0X01;//TIM1使能
}
void EXTI_init(void)
{
EXTI_CR1=0x02;//EXTI0中断使能
}
/**************************LCD******************/
void write(uchar byte,uchar cd)//cd=1写指令cd=0写数据
{
E=0;
if(cd==1)
RS=0;
if(cd==0)
RS=1;
RW=0;
DB_WR_init();
E=1;
quickdelay(1);
DB0=0X01&byte;
DB1=0X02&byte;
DB2=0X04&byte;
DB3=0X08&byte;
DB4=0X10&byte;
DB5=0X20&byte;
DB6=0X40&byte;
DB7=0X80&byte;
quickdelay(10);
E=0;
quickdelay(1);
}
void write_char(uchar *add,uchar a) //用指针
{
uchar i;
write(0x80,1); //从第一行开始显示
for(i=0;i<a;i++) //汉字两字节,字母一字节
{
write(*add,0);
add++; //指针加,指向下一个字节
}
}
void busytest(void)
{
DB_RD_init();
RS=0;
RW=1;
E=1;
while(DB7I);
E=0;
}
uchar readbyte(void)
{
uchar dat,sp,sp2;
E=0;
busytest();
DB_RD_init();
RS=1;
RW=1;
E=1;
quickdelay(1);
dat=0x7E&PB_IDR;
dat=dat/2;
if(DB6I==1)
dat=dat|0x40;
if(DB7I==1)
dat=dat|0x80;
E=0;
return dat;
}
void lcd_clear(void)//清除图形缓存
{
uchar i,j;
write(0x34,1);
for(i=0;i<32;i++)
{
write(0x80+i,1);
write(0x80,1);
for(j=0;j<32;j++)
write(0x00,0);
}
write(0x30,1);
}
void point(uchar x,uchar y,uchar color)
{
uchar byte;
uchar datH,datL,sp;
x=x-1;
y=y-1;
write(0x34,1);//扩充指令
write(0x36,1);//绘图功能
line=x>>4;
byte=x&0x0f;
if(y<32)
row=y;
else
{row=y-32;line=line+8;}
write(0x80+row,1);
write(0x80+line,1);//确定大列和行位置
readbyte();//空读
datH=readbyte();
datL=readbyte();
write(0x80+row,1);
write(0x80+line,1);//读取地址会加一
if(color==1)//点亮点
{
if(byte<8) {datH |= (1<<(7-byte));}
else { datL |= (1<<(15-byte));}
}
if(color==0)
{
if(byte<8) datH &= ~(1<<(7-byte));
if(byte>=8) datL &= ~(1<<(15-byte));
}
write(datH,0);
write(datL,0);
write(0x30,1);
}
void LCD_init(void)
{
busytest();
write(0x30,1);//8 位介面,基本指令集
busytest();
write(0x0c,1);//显示打开,光标关,反白关
busytest();
write(0x01,1);//清屏,将DDRAM的地址计数器归零
delay(10);
}
/**********************按键*******************/
/***********************main*******************************/
main()
{
uchar i;
GPIO_init();
CLK_init();
EXTI_init();//外部中断准备
TIM1_init();//定时器准备
LCD_init();//初始化 清屏
lcd_clear();//清除图形缓存
point(1,1,1);
point(2,1,1);
_asm("rim");
while (1)
{
point(1,1,1);
point(2,1,1);
point(2,2,1);
}
}
@far @interrupt void EXIT0(void)
{
EXTI_SR1|=0x01;//清除中断标志位
}
@far @interrupt void TIM1_irq(void)
{
TIM1_SR1=0x00;
RAMDON++;
if(RAMDON>4095)
RAMDON=0;
}
本帖最后由 echain 于 2016-2-25 22:53 编辑
只要去掉_asm("rim")语句程序就可以运行下去 。
不知道是不是我的中断标志位的问题,可是清除标志位和初始化中断在只操作一个LED灯时都是可以的。
好奇怪
单独贴出初始化和响应函数
void TIM1_init(void)
{
CLK_PCKENR2 |= 0x02;//使能TIM1外围时钟
TIM1_CR1=0X00;//向上计数,无预装载
TIM1_IER=0X01;//更新中断使能
TIM1_PSCRH=0X80;
TIM1_PSCRL=0X00;//32768分频
TIM1_ARRH=0X00;
TIM1_ARRL=0Xcc;//重装载值
TIM1_CR1|=0X01;//TIM1使能
}
void EXTI_init(void)
{
EXTI_CR1=0x02;//EXTI0中断使能
}
@far @interrupt void EXIT0(void)
{
EXTI_SR1|=0x01;//清除中断标志位
}
@far @interrupt void TIM1_irq(void)
{
TIM1_SR1=0x00;
RAMDON++;
if(RAMDON>4095)
RAMDON=0;
}
不懂,帮顶一下~ 回到未来~ 发表于 2016-2-26 09:42
不懂,帮顶一下~
多谢{:2_27:} 中断看看 :):):):):):):) 大面积贴代码貌似不合适啊:(
STM8L051也遇到这问题,单步汇编发现是跳入中断而对应的中断服务函数没有写造成死循环(我是因为DS18b20端口输出模式时CR2寄存器设置1,然后程序改为输入模式,这时候CR2寄存器值还是1造成中断。)
页:
[1]