你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8L152 _asm("rim");语句后程序卡住

[复制链接]
echain 提问时间:2016-2-25 22:47 /
最近正在使用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;
}

收藏 评论7 发布时间:2016-2-25 22:47

举报

7个回答
echain 回答时间:2016-2-25 22:51:35
本帖最后由 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:15
不懂,帮顶一下~
echain 回答时间:2016-2-26 11:06:38

多谢
zykzyk-93033 回答时间:2016-2-26 16:23:53
中断看看
zcl201207 回答时间:2016-2-26 20:38:58
zhoupxa 回答时间:2016-2-28 10:00:21
大面积贴代码貌似不合适啊
hdhgsdhuers 回答时间:2020-4-26 19:48:35
无标题.jpg
STM8L051也遇到这问题,单步汇编发现是跳入中断而对应的中断服务函数没有写造成死循环(我是因为DS18b20端口输出模式时CR2寄存器设置1,然后程序改为输入模式,这时候CR2寄存器值还是1造成中断。)
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版