论坛风格切换切换到宽版
  • 31989阅读
  • 79回复

[分享]每天进步一点点 [复制链接]

上一主题 下一主题
离线linbei1988
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2010-08-23
— 本帖被 renesasrulz 执行置顶操作(2010-09-30) —
开始学习瑞萨单片机,顺便练习下C语言;之前一直用在PIC和义隆的8位单片机,只能汇编程序容得下
已经弄了几个项目,觉得一直汇编下去没什么前途,想从C语言入门来使自己提升一下
来论坛是想有麻烦的时候大家能提醒一下,同时也很愿意更大家分享经验
这算是一个学习日志,不定时更新,写下自己的学习心得,希望大家一起进步
也希望被指出错误,学习改进
根据前辈遗留下来的E8a仿真器和光盘,公司的(代理商送的);由于之前的前辈,搞定了R8C1B的程序之后,连人带程序都消失了;这个芯片一直没量,我都不好意思找代理的技术支持。
装好软件之后,一下蒙了,不知道从哪里下下手;还好找到这个网站,参考本论坛的“瑞萨单片机入门教程汇总”实在是很有用。
将E8a仿真器连接上后,想随便试试几个IO口输出;怎么写怎么错误,于是想到是不是需要包含头文件;搜索了一下安装目录,在Renesas\Hew\System\Pg\Renesas\M16C\V5_42_0\Generate\sfr\R8C的文件夹里找到了,头文件的第一行有2007.01的字需要把它注释掉,不然就会提示错误;不知道为什么会有这个字在而没有被注释掉???
接下来随便写了个IO口驱动的语句pd1_5=1;p1_5=1;成功驱动IO口,总算是踏出了第一步;值得注意的是设定IO口输入输出模式,一般我以前用的单片机都是输入设定为1,输出设定为0,这个刚好相反。我本来写的写的驱动语句是pd1=0xff;p1=0xff;想全部输出,在编译时没有错误;可是执行起来却没有反应?为什么?
带着疑惑,继续我的瑞萨之旅!
重新编辑下,把程序贴在2L给大家方便查看
[ 此帖被linbei1988在2011-08-11 16:01重新编辑 ]
2条评分
renesasrulz 铜币 +10 鼓励一下。 2010-08-23
su37sm 铜币 +20 鼓励,最近没空照顾论坛,偶尔上上都看到不错的上进帖,希望能坚持 2010-08-23
离线linbei1988

只看该作者 沙发  发表于: 2010-08-23
产品最后胎死腹中,程序可能还有BUG。基本功能没有问题
/***********************************************************************/
/*                                                                     */
/*  FILE        :ResM6.c                                               */
/*  DATE        :Sat, Aug 28, 2010                                     */
/*  DESCRIPTION :main program file.                                    */
/*  CPU GROUP   :1B                                                    */
/*                                                                     */
/*  This file is generated by Renesas Project Generator (Ver.4.8).     */
/*                                                                     */
/***********************************************************************/
/*    保护寄存器PRCR对应功能寄存器                                       */
/*    prc0:cm0,cm1,ocd,hra0,hra1,hra2                                       */
/*    prc1:pm0,pm1                                                       */
/*    prc3:vca2,vw1c,vw2c                                                   */
/***********************************************************************/
#include    "sfr_r81B.h"

#define        unchar            unsigned    char
#define        unint            unsigned    int
#define        unlong            unsigned    long

#define        YRE_OUT            p1_0
#define        POWER_OUT        p1_2
#define        LED_OUT            p1_3
#define        START_OUT        p1_4
#define        ACC_OUT            p1_5
#define        OFF_OUT            p1_6
#define        LIGHT_OUT        p1_7
#define        LEARN_IN        p1_7

#define        YSET_OUT        p3_3
#define        SIREN_OUT        p3_4
#define        SHOCK_IN        p3_5
#define        RF_IN            p3_7

#define        RIGHT_IN        p4_5
#define        ACC_IN            p4_6
#define        LEFT_IN            p4_7


#define BLOCK_A     ((unchar *)0x2400)    //BLOCK_A头地址
#define BLOCK_A_END ((unchar *)0x27ff)    //BLOCK_A尾地址
#define BLOCK_B     ((unchar *)0x2800)    //BLOCK_B头地址
#define BLOCK_B_END ((unchar *)0x2bff)    //BLOCK_B尾地址

unlong        had_addr;            //之前一次的遥控信号
unlong        now_addr;            //遥控实时接收数据寄存器

unlong        old1_addr;            //已写入的第一组遥控
unlong        old2_addr;            //已写入的第二组遥控
unlong        old3_addr;            //已写入的第三组遥控
unlong        old4_addr;            //已写入的第四组遥控

unchar        shock_memory;        //灵敏度记忆
/***********************************************************************/
union{
struct                
{
unchar    ready:1;    //预备防盗标志
unchar    guard:1;    //防盗标志
unchar    speak:1;    //语音状态标志
unchar    shutup:1;    //静音标志
}bit;
unchar  byte;
}memory_addr;        //记忆标志

#define        memory_flag        memory_addr.byte
#define        ready_flag        memory_addr.bit.ready
#define        guard_flag        memory_addr.bit.guard
#define        speak_flag        memory_addr.bit.speak
#define        shutup_flag        memory_addr.bit.shutup

/***********************************************************************/
unchar        heist_flag;            //骑劫标志

unchar        ready_count;        //防盗延时

unchar        power_delay;        //语音电源延时

unchar        learn_flag;
unint        learn_count;        //写码按键计时
unchar        learn_counth;        //写码倒计时
unchar        addr_count;            //写入遥控计数

unchar        light_count;        //闪灯间隔
unchar        light_buffer;        //间隔时间缓存    
unchar        light_counth;        //闪灯次数

unchar        led_flag;            //LED标志
unchar        led_count;            //LED闪烁间隔
unchar        led_counth;            //LED闪烁次数
unchar        led_delay;            //LED延时时间

unchar        prex_buffer;
unchar        tx_buffer;            //X定时器缓存区
unchar        siren_flag;            //报警音循环记号
unchar        siren_count;        //相同频率循环次数
unchar        siren_counth;        //同一声音循环次数
unint        bibi_count;            //哔哔声停顿延时
unint        bibi_buffer;
unchar        bibi_counth;        //哔哔声次数

unchar        done_flag;
unchar        key_delay;            //按键防抖延时
unchar        key_keep;            //按键长按计时

unchar        start_flag;
unchar        start_count;        //启动计数

unchar        shock_flag;
unchar        shock_delay;        //预报警

unchar        acc_flag;            //ACC标志
unchar        acc_count;
unchar        acc_learn;
unchar        acclearn_count;        //ACC学码标志

unchar        alarming_flag;        //正在报警标志
unint        alarming_count;        //报警时间

unchar        reguard_flag;
unint        reguard_count;        //恢复防盗状态        

unchar        remind_flag;
unchar        remind_count;        //提醒设防标志

unchar        findout_flag;
unint        findout_count;        //寻车

unchar        *read_addr;            //读取地址指针
unchar        *write_addr;        //写地址指针


void    set_osc(unchar    DEV,unchar    HIGH_LOW,unchar    OUT_IN);    //震荡频率设置
/************************************************************************
*功能 :  时钟初始化处理程序
    DEV            1    2    4    8    16    分频率
    HIGH_LOW    0--低速        1--高速
    OUT_IN        0--内部时钟    1--外时钟
************************************************************************/

void    set_io(void);                    //IO口设置
void    set_intX(void);                    //X定时器中断设定
void    set_intZ(void);                    //Z定时器中断设定
void    set_wdt(void);                    //看门狗初始化
void    learn_test(void);                //学习键检测
unchar    rf_data(void);                    //信号接收
void    learn_pro(void);                //遥控学习
void    data_pro(void);                    //遥控按键功能实现
void    acc_test(void);                    //ACC检测
void    right_left(void);                //转向灯检测
unchar    shock_test(void);                //震动检测
void    release_all(void);                //紧急解除
void    alarm_set(unchar alarm_lv);        //报警程序
void    delay(unint);                    //延时
void    first_key(void);                //按键1功能
void    shutup_key(void);                //静音设防
void    second_key(void);                //按键2功能
void    third_key(void);                //按键3功能
void    start_motor(void);                //启动机车
void    speak_set(void);                //语音转换
void    shock_set(void);                //震动灵敏度调节
void    fourth_key(void);                //按键4功能
void    stop_find(void);                //停止寻车
void    real_speak(unchar time);        //真人语音
void    siren_set(unchar time,unint    flz,unchar    fin);    //报警声音设置
void    reguard_pro(void);                //自动设防
void    remind_pro(void);                //提示防盗
void    program_memory(void);            //编辑闪存
void    read_memory(void);                //读取闪存
unchar    make_addr(void);                //设置闪存地址
unchar    write_memory(void);                //写闪存
unchar    block_erase(unchar *ers_addr);    //闪存块擦除


#pragma interrupt TimerXInt(vect=22);
void    TimerXInt(void)
{
    wdtr=0x00;
    wdtr=0xff;
    ir_txic=0;
    switch(siren_flag)
{
    case 1 :if(siren_count!=12)break;    //报警音
{
    siren_count=0;prex_buffer++;
    if(prex_buffer==60)
    {
    prex_buffer=30;
    if(bibi_counth)
    {bibi_count=bibi_buffer;bibi_counth--;
    if(!bibi_counth){txs=0;while(txs!=0);}}
    else{siren_counth++;}
    }
    if(siren_counth==20)
    {if(!heist_flag){txs=0;while(txs!=0);findout_flag=0;}
    siren_counth=0;siren_flag=2;prex_buffer=60;}
    prex=prex_buffer;tx=tx_buffer;
}break;

    case 2 :if(siren_count!=10)break;    //治安音
{
    siren_count=0;prex_buffer++;
    if(prex_buffer==100)
    {
    prex_buffer=60;
    if(bibi_counth)
    {bibi_count=bibi_buffer;bibi_counth--;
    if(!bibi_counth){txs=0;while(txs!=0);}}
    else{siren_counth++;}
    }
    if(siren_counth==8){siren_counth=0;siren_flag=3;prex_buffer=160;}
    prex=prex_buffer;
}break;
    
    case 3 :if(siren_count!=10)break;    //开道音
{
    siren_count=0;prex_buffer--;
    if(prex_buffer==100){prex_buffer=160;siren_counth++;}
    if(siren_counth==5){siren_counth=0;siren_flag=4;prex_buffer=250;}
    prex=prex_buffer;
}break;
    case 4 :if(siren_count!=230)break;
{
    siren_count=0;
    prex_buffer=185;tx_buffer=15;siren_flag=5;
    prex=prex_buffer;tx=tx_buffer;
}break;
    
    case 5 :if(siren_count!=80)break;    //4+5救护音
{
    siren_count=0;
    prex_buffer=250;tx_buffer=3;
    siren_counth++;
    if(siren_counth==6)
    {siren_counth=0;siren_flag=1;prex_buffer=30;tx_buffer=3;}
    else{siren_flag=4;}
    prex=prex_buffer;tx=tx_buffer;
}break;

}
    if(bibi_count)bibi_count--;            //单音鸣叫延时
    else
    {
    if(SIREN_OUT){SIREN_OUT=0;siren_count++;}
    else{SIREN_OUT=1;}
    }
}



#pragma    interrupt TimerZInt(vect=24);
void    TimerZInt(void)
{
    wdtr=0x00;
    wdtr=0xff;
    ir_tzic=0;                    //清IR位
    

    if(acc_learn)            //ACC学码时限
{
    acc_count--;
    if(!acc_count)
    {acc_learn=0;
    acclearn_count=0;}
}

    if(learn_flag)            //学码倒计时
{
    learn_counth++;
    if(learn_counth==200)
    {LIGHT_OUT=0;
    learn_flag=0;}
}

    if(power_delay)            //语音电源延时
{
    power_delay--;
    if(!power_delay)POWER_OUT=0;
}

    if((ready_count)&&(ready_flag))    //防盗延时程序
{
    ready_count--;
    if(!ready_count)guard_flag=1;
}

    if(light_counth)        //闪灯程序
{
    light_count--;
    if(!light_count)
    {
    light_count=light_buffer;
    if(LIGHT_OUT)
    {LIGHT_OUT=0;if(!heist_flag)light_counth--;}
    else{LIGHT_OUT=1;}
    }
}

    if(ready_flag)          //LED闪烁程序
{
    if(!led_delay)
    {
    led_count--;
    if(!led_count)
    {
    if(LED_OUT){LED_OUT=0;led_counth++;led_count=4;}
    else{LED_OUT=1;led_count=4;}
    }
    switch(led_flag)
    {
    case 1:if(led_counth==2){led_counth=0;led_delay=20;}break;    //普通闪烁
    case 2:if(led_counth==3){led_counth=0;led_delay=20;}break;    //受震动触发
    case 3:if(led_counth==5){led_counth=0;led_delay=20;}break;    //受ACC触发
    }
    }
    else{led_delay--;}
}

    if(start_flag)            //启动键按2次限时
{
    start_count--;
    if(!start_count)start_flag=0;
}

    if((shock_delay)&&(!alarming_flag))        //恢复到预报警状态限时
{
    shock_delay--;
    if(!shock_delay)shock_flag=0;
}    

    if(alarming_flag)        //报警状态
{
    alarming_count--;
    if(alarming_count==15)OFF_OUT=0;
    if(!alarming_count)alarming_flag=0;
}

    if(reguard_flag==1)        //自动防盗
{
    reguard_count--;
    if(!reguard_count)reguard_flag=2;
}

    if(remind_flag==1)        //提示设防
{
    remind_count--;
    if(!remind_count)remind_flag=2;
}

}


void main(void)
{
    unchar    bank_flag=0,rf_flag=0;
    unchar    alarm_flag=0;
    set_osc(8,1,0);                        //调整震荡频率,分频
    delay(15000);
    set_io();                            //IO口初始化
    asm("FCLR I");
    set_wdt();                            //看门狗初始化
    set_intX();
    set_intZ();                            //设定中断
    bank_flag=make_addr();                //设置闪存地址
    if(bank_flag==0)
    read_memory();                        //读取闪存
    asm("FSET I");
    while(1)
{
    wdtr=0x00;
    wdtr=0xff;                            //喂狗

    rf_flag=rf_data();                    //接收
    if(learn_flag)        //写码状态
  {
    if(rf_flag)
    learn_pro();
  }
    else
  {
    data_pro();                            //按键功能实现
    if(!heist_flag)    //防抢跳过检测
   {
    acc_test();    
    if(!ready_flag)
    {
    learn_test();                        //写码按键检测
    if(acc_flag)right_left();            //左右转语音
    if(reguard_flag==2)reguard_pro();    //自动设防
    if(remind_flag==2)remind_pro();        //提示防盗
    }
    if(guard_flag)
    {
    if((!alarming_flag)&&(!findout_flag))alarm_flag=shock_test();//震动检测
    if((!alarming_flag)||(acc_flag==1))alarm_set(alarm_flag);    //报警
    }
   }
    if(heist_flag||alarming_flag)release_all();//紧急解除
  }

}//while

}

/******************fRING-FAST=8MHZ,8分频,单周期指令为1us*****************/
void    set_osc(unchar    DEV,unchar    HIGH_LOW,unchar    OUT_IN)
{
    prc0=1;        //关闭寄存器保护
    switch(DEV)        //分频率
{
    case 1:    cm16=0;cm17=0;cm06=0;break;        //f1
    case 2:    cm16=1;cm17=0;cm06=0;break;        //f2
    case 4:    cm16=0;cm17=1;cm06=0;break;        //f4
    case 8:    cm16=0;cm17=0;cm06=1;break;        //f8
    case 16:cm16=1;cm17=1;cm06=0;break;        //f16
    default:break;
}
     if(HIGH_LOW)    //1为内部高速,0为内部低速
{
    hra00=1;    //高速内部振荡器振荡
    hra01=1;    //使用内部高速振荡器时钟(FRING-Fast)作为内部时钟(FRING)
}
    else        //低速时钟
{
    cm14=0;        //低速内部振荡器振荡
    hra01=0;    //使用内部低速振荡器时钟(FRING-Fast)作为内部时钟(FRING)
}
    if(OUT_IN)        //1为外部时钟,0为内部时钟
{
    cm13=1;    //XIN-XOUT引脚连接内部起振电路
    cm15=1;    //XIN-XOUT引脚使用高驱动能力
    cm05=0;    //开始振荡
    asm("NOP\nNOP\nNOP\nNOP");
    asm("NOP\nNOP\nNOP\nNOP");
    asm("NOP\nNOP\nNOP\nNOP");
    ocd2=0;    //使用主时钟作为系统时钟
}
    else    //使用内部时钟
{
    asm("NOP\nNOP\nNOP\nNOP");
    ocd2=1;    //使用内部时钟作为系统时钟
}
    prc0=0;    //打开寄存器保护
}
/*内置震荡调整完毕,定时器X的fRING=fRING-FAST,定时器C的fRING128=fRING的128分频*/

/*IO口设定函数*/
void    set_io()
{
    pd1=0xff;
    pd3=0x18;
    pd4=0x00;    //IO口输入输出定义
//    pu07=1;    
//    pu11=1;        //允许p3_5,p3_7,p4_5内部上拉
    drr=0x0f;    //将p1_0-p1_3的输出驱动能力设置为high
    p1=0x00;
    p3=0x00;
    p4=0x00;
}

/*看门狗初始化函数*/
void    set_wdt()
{
    prc1=1;        //关闭寄存器保护位
    pm12=1;        //设定看门狗复位
    prc1=0;        //开启寄存器保护位
    wdtr=0x00;
    wdtr=0xff;    //初始化看门狗定时器
    wdts=0xff;    //启动看门狗
}

/*中断X设定函数*/
void    set_intX()
{
    txck0=1;
    txck1=0;    //f8
    prex=31-1;
    tx=4-1;        //
    txmr=0x00;    //定时器模式
    txic=6;        //中断优先级别
    ir_txic=0;    //定时器X溢出标志
}

/*中断Z设定函数*/
void    set_intZ()
{
    tzck0=1;
    tzck1=0;    //f8
    prez=251-1;
    tzpr=201-1;    //50ms中断一次
    tzmr=0x00;    //
    pum=0x00;    //定时器模式
    tzic=6;        //中断优先级别
    ir_tzic=0;    //定时器Z溢出标志
    tzs=1;
    while(tzs!=1);            //定时器X开始计数
}


/*信号接收函数*/
unchar    rf_data()
{
    unchar    h=0,l=0,i=0,n=0,t_back=1;        //i位同步计数,n为数据位移量
    unint    s=0;
    
    wdtr=0x00;
    wdtr=0xff;                                //看门狗定时器
    
    while((t_back==1)&&(s<=100))    //同步
{
    for(s=0;RF_IN==0;s++)if(s>800)break;
    if(s>100)continue;
    for(h=0;RF_IN==1;h++)if(h>80){t_back=0;break;}
    i++;
    if(i>25)t_back=0;
}
    while((t_back==1)&&(n!=24))
{
    for(h=0;RF_IN==1;h++)if(h>80){t_back=0;break;}
    for(l=0;RF_IN==0;l++)if(l>80){t_back=0;break;}
    n++;
    if(h>l)
    {now_addr<<=1;now_addr|=0x00000001;}            //"1"
    else
    {now_addr<<=1;now_addr&=0xfffffffe;}            //"0"
    if((h==0)||(l==0)){t_back=0;break;}
}

    if(t_back==1)        //是否超时
{
    key_delay=0;
    now_addr&=0x00ffffff;
}
    else
{
    key_delay++;
//    if(key_delay==4)        //按键按过松开
    now_addr=0;
    if(key_delay==4)        //没有按键按下
    {key_delay=0;
    key_keep=0;}//超时,清除遥控记录
}
    return    t_back;
}

/*遥控学习函数*/
void    learn_pro()
{
    unchar    proof=0;
    addr_count++;
    switch(addr_count)
{
    case 1: old1_addr=now_addr;rf_data();
    if(old1_addr==now_addr)proof=1;break;    //校对
    case 2: old2_addr=now_addr;rf_data();
    if(old2_addr==now_addr)proof=1;break;    //校对
    case 3: old3_addr=now_addr;rf_data();
    if(old3_addr==now_addr)proof=1;break;    //校对
    case 4: old4_addr=now_addr;rf_data();
    if(old4_addr==now_addr)proof=1;break;    //校对
}
    if(proof)    //校对成功
{
    old1_addr&=0x00fffff0;
    old2_addr&=0x00fffff0;
    old3_addr&=0x00fffff0;
    old4_addr&=0x00fffff0;    //去除按键位
    program_memory();        //写入闪存
    LIGHT_OUT=0;
    delay(15000);
    LIGHT_OUT=1;
    delay(15000);
    LIGHT_OUT=0;
    delay(15000);
    LIGHT_OUT=1;
    delay(25000);
    learn_counth=0;
    if(addr_count==4)
  {
    learn_flag=0;
    LIGHT_OUT=0;
    reguard_flag=0;            //重新设防标志
    remind_flag=0;            //提示设防标志
    had_addr=0;    
  }
}
    else            //校对失败
{    
    addr_count--;
}

}

//上电后设置闪存地址和读取闪存记忆
//设置闪存读取地址
unchar    make_addr()
{
    unchar    read_data[16];
    unchar    empty=0,i=0;
    unchar    memory_blank=0;

    read_addr=BLOCK_A;
    fmr0=0x01;
    asm("NOP ");
    fmr0=0x03;                //CPU改写模式有效
    fmr1=0x80;
    asm("NOP ");
    fmr1=0x82;                //EW1模式
    *read_addr=0xff;        //读阵列模式
    do
{    
    empty=1;
    for(i=0;i!=0x10;)
  {
    read_data=*read_addr;
    read_addr+=1;
    i++;
  }
    for(i=0;i!=0x10;)
  {
    if(read_data!=0xff)empty=0;
    i++;
  }
    
}
    while((BLOCK_B_END>read_addr)&&(empty==0));
    fmr0=0x01;                //CPU改写模式无效
    read_addr-=0x10;        
    write_addr=read_addr;    //下次写入地址
    read_addr-=0x10;        //设置闪存读取地址
    if(read_addr<BLOCK_A)    //全部空白
{
    write_addr=BLOCK_A;        
    memory_blank=1;        //闪存全空标志,不读闪存
}
    return    memory_blank;
}

//读闪存
void    read_memory()
{
    unchar    read_data[16]=0;
    unchar    i;
    fmr0=0x01;
    asm("NOP ");
    fmr0=0x03;                //CPU改写模式有效
    fmr1=0x80;
    asm("NOP ");
    fmr1=0x82;                //EW1模式
    *read_addr=0xff;        //读阵列模式
    for(i=0;i!=0x10;)
{
    read_data=*read_addr;
    read_addr+=1;
    i++;
}
    fmr0=0x01;                //CPU改写模式无效
    read_addr-=0x10;            //回复读取地址
    old1_addr=read_data[2];                    //遥控1
    old1_addr<<=8;old1_addr|=read_data[1];
    old1_addr<<=8;old1_addr|=read_data[0];
    old2_addr=read_data[5];                    //遥控2
    old2_addr<<=8;old2_addr|=read_data[4];
    old2_addr<<=8;old2_addr|=read_data[3];
    old3_addr=read_data[8];                    //遥控3
    old3_addr<<=8;old3_addr|=read_data[7];
    old3_addr<<=8;old3_addr|=read_data[6];
    old4_addr=read_data[11];                //遥控4
    old4_addr<<=8;old4_addr|=read_data[10];
    old4_addr<<=8;old4_addr|=read_data[9];
    memory_flag=read_data[12];                //防盗状态
    shock_memory=read_data[13];                //震动灵敏度
    if(memory_flag!=0xff)
{
    if(ready_flag)
  {
    ready_count=100;        //防盗延时
    led_flag=1;                //LED标志,未触发
    led_count=4;            //LED闪灯频率
    led_counth=0;            //LED闪灯次数
    led_delay=0;            //LED闪灯间隔时间
  }

}
    else{memory_flag=0;}                    //第一次开机默认    

}

//编辑闪存
void    program_memory()
{
    unchar    fail=0;
    asm("FCLR I");

    do
{
    if(write_addr==BLOCK_B_END+1)
    fail=block_erase(BLOCK_A);        //擦除块A
    if(write_addr==BLOCK_A_END+1)
    fail=block_erase(BLOCK_B);        //擦除块B    

    if(fail==88)                    //擦除失败
    fail=block_erase(BLOCK_A);        //擦除块A
    if(fail==88)                    //擦除失败
    fail=block_erase(BLOCK_B);        //擦除块B


    fail=write_memory();            //读取闪存
}
    while(fail==55);                //写入错误时,尝试是否需要擦除
    asm("FSET I");
}


//块擦除
unchar    block_erase(unchar *ers_addr)
{
    unchar    ers_fail=88,back=0;
    
    fmr0=0x01;
    asm("NOP ");
    fmr0=0x03;                        //CPU改写模式有效
    fmr1=0x80;
    asm("NOP ");
    fmr1=0x82;                        //EW1模式

    *ers_addr=0x20;
    *ers_addr=0xd0;                    //块擦除模式
    while(fmr00!=1);
    if(fmr07==1)
    {back=ers_fail;*ers_addr=0x50;}    //返回错误标志
    fmr0=0x01;                        //CPU改写模式无效
    if(ers_addr==BLOCK_A)
    write_addr=BLOCK_A;
    else
    write_addr=BLOCK_B;                //重设读写地址
    return    back;                    //返回确认
}

//写入闪存
unchar    write_memory()
{
    unchar    ers_fail=55,back=0;
    unchar    write_data[16]=0;
    unchar    i;
    write_data[0]=old1_addr;write_data[1]=(old1_addr>>8);write_data[2]=(old1_addr>>16);
    write_data[3]=old2_addr;write_data[4]=(old2_addr>>8);write_data[5]=(old2_addr>>16);
    write_data[6]=old3_addr;write_data[7]=(old3_addr>>8);write_data[8]=(old3_addr>>16);
    write_data[9]=old4_addr;write_data[10]=(old4_addr>>8);write_data[11]=(old4_addr>>16);
    write_data[12]=memory_flag;write_data[13]=shock_memory;//保存数据
    
    fmr0=0x01;
    asm("NOP ");
    fmr0=0x03;                        //CPU改写模式有效
    fmr1=0x80;
    asm("NOP ");
    fmr1=0x82;                        //EW1模式    
    
    for(i=0;i!=0x10;)
{
    *write_addr=0x40;                //闪存写入模式
    *write_addr=write_data;        //闪存数据写入
    write_addr++;
    i++;
    while(fmr00!=1);
    if(fmr06==1)
    {back=ers_fail;*write_addr=0x50;}//错误标志
}
    fmr0=0x01;
    return    back;
}

//按键功能实现
void    data_pro()
{
    unlong    key_addr=0,data_addr=0;


    data_addr=now_addr;
    data_addr&=0x00fffff0;        //保存数据位
    key_addr=now_addr;
    key_addr&=0x0000000f;        //保存按键位

    if(((data_addr==old1_addr)||(data_addr==old2_addr)||
    (data_addr==old3_addr)||(data_addr==old4_addr))&&(data_addr&&key_addr))//正确的码
{
    key_delay=0;
    had_addr=now_addr;
    if(!(heist_flag||alarming_flag))
{
    switch(key_addr)
   {
    case 8:    key_keep++;if(key_keep==10)shutup_key();break;
    case 2:    if(!ready_flag){key_keep++;if(key_keep==40)speak_set();}break;
    case 4:    start_motor();break;
    case 1:    if(!ready_flag){key_keep++;if(key_keep==40)shock_set();}break;
   }

    while(done_flag)
   {
    done_flag=rf_data();
    key_addr=now_addr;
    if(!((data_addr==old1_addr)||(data_addr==old2_addr)||
    (data_addr==old3_addr)||(data_addr==old4_addr)))done_flag=0;
   }
    START_OUT=0;
}

}

    else
{
    data_addr=had_addr;
    data_addr&=0x00fffff0;        //保存数据位
    key_addr=had_addr;
    key_addr&=0x0000000f;        //保存按键位

    if(((data_addr==old1_addr)||(data_addr==old2_addr)||
    (data_addr==old3_addr)||(data_addr==old4_addr))&&(data_addr&&key_addr))//正确的码
{    
    had_addr=0;
    switch(key_addr)
   {
    case 8:    if(heist_flag)break;first_key();break;
    case 2:    second_key();break;
    case 4:    if(heist_flag||alarming_flag)break;third_key();break;
    case 1:    if(heist_flag||alarming_flag)break;fourth_key();break;
   }
}
}


}

/*闭锁键*/
void    first_key()
{
    unchar    i;
    
    if(findout_flag)stop_find();    //寻车
    else
{
    SIREN_OUT=0;
    txs=0;
    while(txs!=0);

    if(speak_flag){siren_set(1,500,1);}
    else{real_speak(1);}
    
    LIGHT_OUT=0;            //闪灯关
    OFF_OUT=0;                //熄火停止
    light_count=5;
    light_buffer=light_count;
    light_counth=1;
    alarming_flag=0;        //清报警标志
    ready_count=60;            //防盗延时
    guard_flag=0;            //清防盗标志
    reguard_flag=0;            //重新设防标志
    remind_flag=0;            //提示设防标志
    shock_flag=0;            //回复预报警
    if((!ready_flag)||(shutup_flag))//不在防盗状态或在静音状态
   {
    shutup_flag=0;
    ready_flag=1;            //预备防盗标志
    led_flag=1;                //LED标志,未触发
    led_count=4;            //LED闪灯频率
    led_counth=0;            //LED闪灯次数
    led_delay=0;            //LED闪灯间隔时间
    program_memory();        //写防盗状态
   }
    for(i=0;ACC_IN==1;i++)if(i>200)break;
    if(i>200)
   {
    heist_flag=1;            //骑劫标志
    siren_set(0,0,2);
    light_count=5;
    light_buffer=light_count;
    light_counth=30;
    ACC_OUT=0;                //ACC停止输出
    OFF_OUT=1;                //熄火
    delay(60000);
   }
}
}


void    shutup_key()
{
    unchar    i;
    
    done_flag=1;
    had_addr=0;
    findout_flag=0;            //寻车
    SIREN_OUT=0;
    txs=0;
    while(txs!=0);

    
    LIGHT_OUT=0;            //闪灯关
    OFF_OUT=0;                //熄火停止
    light_count=5;
    light_buffer=light_count;
    light_counth=1;
    alarming_flag=0;        //清报警标志
    ready_count=60;            //防盗延时
    guard_flag=0;            //清防盗标志
    reguard_flag=0;            //重新设防标志
    remind_flag=0;            //提示设防标志
    shock_flag=0;            //回复预报警
    if((!shutup_flag)||(!ready_flag))//不在静音状态或不在防盗状态
  {
    shutup_flag=1;
    ready_flag=1;            //预备防盗标志
    led_flag=1;                //LED标志,未触发
    led_count=4;            //LED闪灯频率
    led_counth=0;            //LED闪灯次数
    led_delay=0;            //LED闪灯间隔时间
    program_memory();        //写防盗状态
  }
    for(i=0;ACC_IN==1;i++)if(i>200)break;
    if(i>200)
  {
    heist_flag=1;            //骑劫标志
    siren_set(0,0,2);
    light_count=5;
    light_buffer=light_count;
    light_counth=30;
    ACC_OUT=0;                //ACC停止输出
    OFF_OUT=1;                //熄火
    delay(60000);
  }    
}


/*开锁键*/
void    second_key()
{
    unchar    i;
    
    if(findout_flag)stop_find();            //寻车
    else
{
    SIREN_OUT=0;
    txs=0;
    while(txs!=0);
    if(!shutup_flag)
  {
    if(speak_flag){siren_set(2,500,1);}
    else{real_speak(2);}
  }
    LIGHT_OUT=0;
    LED_OUT=0;
    led_flag=0;
    light_count=5;
    light_buffer=light_count;
    light_counth=2;
    heist_flag=0;            //清除骑劫标志
    alarming_flag=0;        //清报警标志
    if(ready_flag)//在防盗状态
  {
    remind_flag=0;            //提示设防标志
    reguard_flag=1;
    reguard_count=600;        //自动恢复标志 30S
    ready_flag=0;
    guard_flag=0;            //清防盗状态
    led_flag=0;                //清LED标志
    program_memory();        //写防盗状态
  }
    else
  {
    remind_flag=0;            //提示设防标志
    reguard_flag=0;
    reguard_count=0;        //自动恢复
  }
    for(i=0;ACC_IN==1;i++)if(i>200)break;
    if(i>200)
  {
    reguard_flag=0;
    remind_flag=1;
    remind_count=160;        //自动提醒标志    8S
    ACC_OUT=0;                //ACC停止输出
    OFF_OUT=1;                //熄火输出
    delay(60000);
  }
    OFF_OUT=0;
}
}

/*语音切换*/
void    speak_set()
{
    done_flag=1;
    had_addr=0;
    if(speak_flag)
{
    real_speak(2);
    speak_flag=0;            //有语音
    light_count=5;
    light_buffer=light_count;
    light_counth=2;
}
    else
{
    light_count=5;
    light_buffer=light_count;
    light_counth=1;
    siren_set(2,500,1);
    speak_flag=1;            //无语音
}
    program_memory();        //写语音状态
    delay(20000);
}

/*启动键*/
void    third_key()        //启动键
{
    if(findout_flag)stop_find();
    start_count=20;
    start_flag=1;
}

void    start_motor()
{
    if(start_flag)
{
    done_flag=1;
    start_flag=0;
    start_count=0;
    ready_flag=0;
    guard_flag=0;
    remind_flag=0;
    reguard_flag=0;
    reguard_count=0;        //自动恢复
    ACC_OUT=1;
    START_OUT=1;
    delay(30000);
}
}

/*寻车键*/
void    fourth_key()
{
    reguard_flag=0;
    reguard_count=0;        //自动恢复
    if(findout_flag)
{
     stop_find();
}
     else
{
    if(!shutup_flag)siren_set(0,0,2);
    findout_flag=1;
    light_counth=15;
    LIGHT_OUT=1;
    light_count=10;
    light_buffer=light_count;    
}

}

void    stop_find()
{
    ready_count=60;            //防盗延时
    guard_flag=0;            //清防盗标志
    findout_flag=0;
    light_counth=0;
    LIGHT_OUT=0;
    txs=0;while(txs!=0);
}


/*震动灵敏度调节*/
void    shock_set()
{
    key_keep=0;
//    done_flag=1;
    had_addr=0;
    light_counth=0;
    LIGHT_OUT=0;
    switch(shock_memory)
{
    case 0:siren_set(2,500,1);shock_memory=1;break;
    case 1:siren_set(3,500,1);shock_memory=2;break;
    case 2:siren_set(4,500,1);shock_memory=3;break;
    case 3:siren_set(1,500,1);shock_memory=0;break;
}
    program_memory();        //写灵敏度
    delay(10000);
}


/*报警音输出*/
void    siren_set(unchar time,unint    flz,unchar    fin)
{
    siren_count=0;            //同一频率循环次数
    siren_counth=0;            //同一声音循环次数
    bibi_buffer=flz;
    bibi_count=bibi_buffer;    //短鸣时间隔,初始值为0
    bibi_counth=time;        //短鸣次数,0为长鸣
    siren_flag=fin;
    switch(fin)
{
    case 1:prex_buffer=31-1;break;
    case 2:prex_buffer=61-1;break;
}
    tx_buffer=4-1;
    prex=prex_buffer;
    tx=tx_buffer;
    txmr=0;
    txs=1;
    while(txs!=1);            //定时器Z开始计数
}

/*语音输出程序*/
void    real_speak(unchar    time)
{
    power_delay=100;        //语音电源延时关闭时间
    POWER_OUT=1;            //语音电源
    delay(1000);
    YRE_OUT=1;
    delay(100);
    YRE_OUT=0;                //语音复位
    for(;time!=0;time--)    //time次数设置语音
{
    YSET_OUT=1;
    delay(40);
    YSET_OUT=0;
    delay(40);
}

}

/*ACC检测*/
void    acc_test()
{
    unchar    i;
    if(acc_flag)
{
    for(i=0;ACC_IN==0;i++)if(i>250)break;
    if(i>200)
  {
    acc_flag=0;
    if(!ready_flag)
   {
    acclearn_count++;
    if(acclearn_count==6)    //ACC打6次
    {LIGHT_OUT=1;
    acclearn_count=0;
    acc_learn=0;
    learn_counth=0;        //学习状态倒计时
    addr_count=0;        //写入遥控计数
    learn_flag=1;}
    if(!acc_learn)
    {acc_learn=1;
    acc_count=160;}        //进入ACC写码倒计时
    if(!remind_flag)
    {remind_flag=1;
    remind_count=160;}    //提示设防
   }
  }
    
}
    else
{
    for(i=0;ACC_IN==1;i++)if(i>250)break;
    if(i>200)
  {
    acc_flag=1;
    reguard_flag=0;
    remind_flag=0;            //关自动设防和提示设防
    if(!ready_flag)
    if(!shutup_flag)
   {
    if(!speak_flag)
    {if(!acc_learn)real_speak(6);}
   }
  }
}

}

/*学习键检测函数*/
void    learn_test()
{
    unchar    i;
    learn_count++;
    if(learn_count==100)
{
    learn_count=0;
    pd1_7=0;
    for(i=0;(LEARN_IN==1)&&(i<=100);i++);
    pd1_7=1;
    if(i>100)
   {
    LIGHT_OUT=1;
    learn_counth=0;        //学习状态倒计时
    addr_count=0;        //写入遥控计数
    learn_flag=1;
   }
}

}



/*转向灯检测*/
void    right_left()
{
    unchar    i,speak=0;
    if((LIGHT_OUT==0)&&(!shutup_flag))
{    
    for(i=0;RIGHT_IN==1;i++)if(i>250)break;
    if(i>200)speak=3;
    for(i=0;LEFT_IN==1;i++)if(i>250)break;
    if(i>200)speak=4;
    if(speak){real_speak(speak);delay(50000);}
}
//    while(RIGHT_IN||LEFT_IN);

}

/*震动检测*/
unchar    shock_test()
{
    unint    shock_count=0,i=0;
    unchar    shock_alarm=0;
    wdtr=0x00;
    wdtr=0xff;
    for(i=0;SHOCK_IN==1;i++)if(i>60000)break;
    if(i>10)
{
    switch(shock_memory)
  {
    case 0:shock_count=10;break;
    case 1:shock_count=1000;break;
    case 2:shock_count=30000;break;
    case 3:shock_count=60000;break;
  }
    
    if(i>shock_count)
  {
    if(!shock_flag)                        //是否预报警
    {shock_alarm=1;}
    else
    {shock_alarm=2;}
    if(alarming_flag)shock_alarm=0;        //正在报警    
  }


}
    return    shock_alarm;

}

/*报警设置程序*/
void    alarm_set(unchar    alarm_lv)
{
    if(acc_flag){alarm_lv=2;led_flag=3;}//有ACC触发
    switch(alarm_lv)
{
    case 1:if(!alarming_flag)        //预报警
  {
    OFF_OUT=1;
    if(led_flag==1)led_flag=2;
    alarming_flag=1;
    alarming_count=90;                //报警时间
    shock_flag=1;
    shock_delay=200;                //预报警延时
    if(!shutup_flag)
   {
    if(speak_flag){siren_set(5,1000,2);}
    else{real_speak(5);}
   }
    light_counth=5;
    light_count=5;
    light_buffer=light_count;
  }break;
    case 2:if(alarming_flag<2)
  {
    OFF_OUT=1;
    alarming_flag=2;
    alarming_count=340;                //报警时间
    if((!shutup_flag)||(acc_flag))siren_set(0,0,2);
    light_counth=30;
    light_count=5;
    light_buffer=light_count;
  }break;
}

}

/*自动防盗*/
void    reguard_pro()
{
    if(!shutup_flag){first_key();}
    else{shutup_key();}
}


/*提示设防*/
void    remind_pro()
{
    remind_flag=0;
    if(!shutup_flag)
{
    if(speak_flag)
    {siren_set(3,500,1);}
    else{real_speak(7);}
}
    light_counth=3;
    light_count=3;
    light_buffer=light_count;
}

void    release_all()
{
    unint    i;
    pd1_7=0;
    for(i=0;(ACC_IN&&LEARN_IN);i++)if(i>45000)break;
    pd1_7=1;
    if(i>45000)second_key();
}


/*延时程序段*/
void    delay(unint    i)        //约为24us
{
    for(;i!=0;i--){wdtr=0x00;wdtr=0xff;
    asm("NOP\nNOP");}
}
[ 此帖被linbei1988在2011-08-11 16:02重新编辑 ]
离线renesasrulz

只看该作者 板凳  发表于: 2010-08-23
继续研究入门教程。你的程序没做初始化工作。

广告招租

email: admin@renesas-mcu.com
QQ: 2020832894
离线macfy
只看该作者 地板  发表于: 2010-08-23
怎么样测试初始化对了,没有逻辑错误了呢
离线watermellon

只看该作者 4楼 发表于: 2010-08-23
加油啊,坚持就是胜利
麒麟电子: https://shop122504791.taobao.com/index.htm?spm=a1z10.3-c.w5002-10984697944.2.Ip33LS
离线小小书童

只看该作者 5楼 发表于: 2010-08-23
纯支持lz一下!!
离线快乐水牛

只看该作者 6楼 发表于: 2010-08-23
精神上支持楼主
离线miracledavid

只看该作者 7楼 发表于: 2010-08-24
回 3楼(macfy) 的帖子
能正常运行就可以了。(I/O口正常工作)。
友情支持。
离线linbei1988

只看该作者 8楼 发表于: 2010-08-27
这几天断断续续看了点R8C1B的资料,在调试过程中遇到也很多麻烦,大部分自己摸索到半知半解的程度。
在看了部分资料后,调试了一点点,现在发现个内部震荡和复位的问题是在难搞。
现在贴上我调试程序,请大侠指点迷津!!
好像该设的寄存器都设了,程序走起来还是内置低频震荡。。郁闷了!
void main(void)
{
/******************fRING-FAST=8MHZ,8分频,单周期指令为1us*****************/
    prc0=1;        //特殊寄存器保护位置1
    cm06=1;        //时钟8分频
    cm14=0;        //低速内部震荡,改变hra01位前必须置0开启
    ocd=0x04;    //主时钟与振荡检测停止,开启内部震荡
    hra00=1;    //高速内部震荡开启,改变hra01位前必须置1开启
    hra01=1;    //开内部高速振荡,出厂默认时钟8MHZ,不调整hra1和hra2寄存器
    prc0=0;        //特殊寄存器保护位置0
    pd1=0xff;
    pd3=0x18;
    pd4=0x00;    //IO口输入输出定义
    pu07=1;    
    pu11=1;        //允许p3_5,p3_7,p4_5内部上拉
    drr=0x0f;    //将p1_0-p1_3的输出驱动能力设置为high
    p1=0x00;
    p3=0x00;
    p4=0x00;
    POWER_OUT=1;
    while(1)
{    
    if(ACC_IN==1)
    {
    YSET_OUT=1;
    asm("nop");
    YSET_OUT=0;
    asm("nop");
    YSET_OUT=1;
    asm("nop");
    YSET_OUT=0;
    DELAY(10);    
    YRE_OUT=1;
    DELAY(2);
    YRE_OUT=0;
    }
}

}

void    DELAY(unchar    i)
{
    unchar    j;
    for(;i!=0;i--)
    {
        for(j=1;j!=0;j++)asm("nop");
    }
}
离线linbei1988

只看该作者 9楼 发表于: 2010-08-28
还有复位的问题,开机后程序不运行。。需要手动将RESET脚拉低才能运行