
RL78 /G13 開發板EEPROM仿真教程
1、開始學習前,大家請準備請下載Renesas 提供的EEPROM摸擬庫和自编程库FDL 庫Type01
EEPROM模拟库.zip
自编程库FDL Type01.zip
2、解壓EEPROM摸擬庫后,用得到的RENESAS_EEL_RL78_T01E_V1.10.exe 生成庫代碼,設置如下圖:
解壓自编程库FDL 庫Type01后,用得到的RENESAS_FDL_RL78_T01E_V1.10.exe生成庫代碼,設置如下圖:
3、在你要加入摸擬EEPROM功能的project目錄下建一個EEPROM目錄,把剛才生成的所有”eel.*”和”fdl.*”文件拷貝到EEPROM目錄內,所有文件如下圖:
4、用IAR打開你的項目,把所有所有”eel.*”和”fdl.*”文件增加到項目內(Workspace),
如下圖藍色框內的文件是新增加進去的:
5、打開fdl_descriptor.h 修改以下兩個參數
/* specify the CPU frequency in [Hz]
#define FDL_SYSTEM_FREQUENCY 32000000 //modify by campo
因為我的時候運為32M,你需要按自己的要求修改
/* specify the size of the EEL pool inside the FAL pool expressed in blocks */
#define EEL_POOL_SIZE 4 //modify by campo
EEL_POOL_SIZE 為什麽要改,大家可以參考文件EEPROM Emulation Library EEL-T01.pdf 的61頁
6、項目option中的linker要做一下修改,如下圖藍色框內的參考,要設為EEPROM目錄中的eel_sample_linker_file.xcl:
7、這里我只是用了原文件里的默認設置,大家可以根據自己的需要,按庫文件里的說明進行修改的。
8、到這里基本上已經完成了EEPROM仿真庫的加入了,可以試一下“Make“,編譯一下,看有沒有錯誤,如沒有錯誤我們就可以進行下一步,寫我們的程序了。
9、打開自己項目主文件,即Main函數的文件,在頭部增加以下代碼:
#include "eeprom/eel.h"
eel_request_t my_eel_request;
unsigned char testbyte;
/* 為什麽定義eel_request_t my_eel_request;* /
/* 為什麽定義這個,大家打開eel_types.h 找到eel_request_t就會明白了 */
/* 再不明白就再打開eel.h 找到EEL_Execute 這個函數的說明 */
/*還是不明白就打開EEPROM Emulation Library EEL-T01.pdf 的71頁仔細看多幾遍*/
我是這樣的,看下圖,藍色框中是這次測試加進去的代碼:
10、下面是我寫的一些代碼進行測試的,大家可以按自己的需要自己寫:
unsigned char Status;
Status=EEL_Init(); // Initialization of the EEPROM Emulation Library (EEL)
if(Status==EEL_OK) // if no error occurred
{
EEL_Open(); // Activates the access to the used flash medium.
my_eel_request.command_enu = EEL_CMD_STARTUP;
my_eel_request.timeout_u08 = 255;
EEL_Execute(&my_eel_request); // start up
if (my_eel_request.status_enu == EEL_OK)
{
;
}
else
{
my_eel_request.command_enu = EEL_CMD_FORMAT;
EEL_Execute(&my_eel_request); //if error format EEPROM
if(my_eel_request.status_enu ==EEL_OK)
{
my_eel_request.command_enu = EEL_CMD_STARTUP;
my_eel_request.timeout_u08 = 255;
EEL_Execute(&my_eel_request);
}
}
testbyte=25;
my_eel_request.address_pu08 = (eel_u08*)&testbyte;
my_eel_request.identifier_u08 = 30;
my_eel_request.command_enu = EEL_CMD_WRITE;
my_eel_request.timeout_u08 = 255;
EEL_Execute(&my_eel_request); //write 1byte data into flash
if(my_eel_request.status_enu == EEL_OK)
{
testbyte=0;
my_eel_request.address_pu08 = (eel_u08*)&testbyte;
my_eel_request.identifier_u08 = 30;
my_eel_request.command_enu = EEL_CMD_READ;
my_eel_request.timeout_u08 = 255;
EEL_Execute(&my_eel_request); //read 1byte data into flash
}
my_eel_request.command_enu = EEL_CMD_SHUTDOWN;
my_eel_request.timeout_u08 = 255;
EEL_Execute(&my_eel_request); //shutdown
EEL_Close(); //Deactivates the access to the used flash medium.
NOP();
}
11、各個API函數的使用,大家可以打開”eel.h”“,”eel_types.h” 看說明,更詳細的,可以看下載的庫文件里的pdf文件,里面有很詳細的說明。
Campozeng
campozeng@gmail.com
2012-9-6
RL78/G13 開發板EEPROM仿真教程PDF文件檔可以從下面連接下載,謝謝。
——回复可见内容——


使用DMA (Direct Memory Access) controller 可以不通過CPU就可以將外設的數據傳到Ram,或者將RAM的數據傳送到外設。
這樣就可以高速傳送大量數據,也將可以做到real-time了。
下面我們學習一下怎麼用DMA
1、我們定義兩個寄存器,把它在Ram中的地址固定下來,如下圖:
2、我們使用Applilet生成基礎代碼,首先們們定義DMA1,將AD轉換的結果傳送到ADCBuffer,設置如下,注意藍色框中部分:
3、定義DMA1,將UART2/RXD2數據傳送到RX2Buffer,設置如下,注意藍色框中部分:
4、然后生成代碼,加到我們的項目中就可以用了,是不是很簡單呢。
調用下面一些函數就可以使用了:
void DMA0_Init(void);
void DMA0_Enable(void);
void DMA0_Disable(void);
void DMA0_Hold(void);
void DMA0_Restart(void);
MD_STATUS DMA0_CheckStatus(void);
void DMA0_SoftwareTriggerOn(void);
MD_STATUS DMA0_SetData(UCHAR sfraddr, USHORT ramaddr, USHORT count);
void DMA0_UserInit(void);
__interrupt void MD_INTDMA0(void);
void DMA1_Init(void);
void DMA1_Enable(void);
void DMA1_Disable(void);
void DMA1_Hold(void);
void DMA1_Restart(void);
MD_STATUS DMA1_CheckStatus(void);
void DMA1_SoftwareTriggerOn(void);
MD_STATUS DMA1_SetData(UCHAR sfraddr, USHORT ramaddr, USHORT count);
void DMA1_UserInit(void);
__interrupt void MD_INTDMA1(void);

IIC的協議就不多描述了,有興趣的朋友可以找相關資料看。
下面開始:
首選把EERPOM的SCL/SDA連接到P60/SCLA0和P61/SDAA0,把A0/A1/A2都接到GND,把EEPROM的slave址設為了0xA0
1、Applilet生成基礎代碼
首先設定MCU的工作時鐘,如下圖:
IICA0模式選擇為Single Master
IICA0設定如下圖
為了測試簡單,先把WDT關了
然后點Generate code,生成后用IAR打開*.eww文件
2、打開CG_serial_user.c文件,改一下代碼,如下圖藍色框中的代碼是我增加進去的,用于發送和接收和完成的標志位
3、打開CG_main.c文件,開始寫我們自己的代碼,如下圖,在頭部定義一此要用的寄存器,見藍色框中部份:
4、然后寫一個簡單的測試程序來測試,我現在把程序寫到main函數中,函數如下:
下面函數的功能主要是:先寫一個字節的數據到EEPROM,寫完后再把數據讀出來,如果讀出的數據與寫進的數據相等,剛把RL78/G13上的LED D2反轉(亮變滅,滅則變亮)。
void main(void)
{
/* Start user code. Do not edit comment generated here */
UCHAR Status,EEAddress;
USHORT i;
__low_level_init(); // init. system
EEAddress=0xA0; // define eeprom slave address
IICWriteCompleteFlag=0; // if write data complete, =1
IICReadCompleteFlag=0; // if read data complete, =1
PU7_bit.no7 = 1;
PM7_bit.no7 = 0;
P7_bit.no7=1; //define the LED on RL78/G13 board
for(i=0;i<50000;i++) //delay
{
NOP();
}
while (1U)
{
if(IICWriteCompleteFlag==0 && IICReadCompleteFlag==0) //if idle
{
IICWriteCompleteFlag=2;
IICWriteBuffer[0]=0x00; //EEPROM add ,thd address where to write data
for(i=1;i<15;i++)
{
IICWriteBuffer[i]=i; //the data what to write
}
/** write 2 byte data,first is address, the second byte is data**/
Status=IICA0_MasterSendStart(EEAddress, IICWriteBuffer, 2, 150);
if(Status != MD_OK)
{
IICWriteCompleteFlag=0;
}
}
else if(IICWriteCompleteFlag==1) //if write complete
{
IICWriteCompleteFlag=0;
IICReadCompleteFlag=2;
for(i=0;i<50000;i++) //delay for eeprom to access the data
{
NOP();
}
for(i=0;i<50000;i++) //delay for eeprom to access the data
{
NOP();
}
/* send address whred to read*/
Status=IICA0_MasterSendStart(EEAddress, IICWriteBuffer, 1, 150);
if(Status != MD_OK)
{
IICReadCompleteFlag=0;
}
else
{
for(i=0;i<50000;i++) //delay for eeprom to access the data
{
NOP();
}
while(IICWriteCompleteFlag==0); // wait write address complete
IICWriteCompleteFlag=0;
/* read out 1 byte data*/
Status=IICA0_MasterReceiveStart(EEAddress, IICReadBuffer, 1, 150);
if(Status!=MD_OK)
{
IICReadCompleteFlag=0;
}
}
}
else if(IICReadCompleteFlag==1) //if read complete
{
IICReadCompleteFlag=0;
if(IICReadBuffer[0]==IICWriteBuffer[1])
{
/*if the read out data equ the data writed before*/
/* flash the led on the rl78/G13 board*/
P7 ^= 0x80;
}
}
for(i=0;i<25000;i++) //delay
{
NOP();
}
}
/* End user code. Do not edit comment generated here */
}
IICA0 EEPROM讀寫程序在下面下載:
——回复可见内容——

IO 模擬IIC 讀寫EEPROM
內置的IICA0/IIC00這些模塊測試一下,好像不太好用,樓上有文檔供大家學習。
現在教大家用IO模擬IIC來讀寫EEPROM.
首先定義SCL/SDA:
#define SDA P7_bit.no5
#define SDA_INPUT PM7_bit.no5
#define SCL P7_bit.no6
#define SCL_INPUT PM7_bit.no6
首先,我們將會用到以下一些函數:
void CreateIICPort(void);
這個涵數用于初始化要用到的IO狀態
void DelayUs(USHORT US);
用于延時DelayUs(5)為延時約5us.
void Start_I2c(void);
啟動IIC總線
void Stop_I2c(void);
停止IIC總線
void SendByte(UCHAR c);
發送一個字節數據
UCHAR RcvByte(void);
接收一個字節數據
void Ack_I2c(UCHAR a);
發送應答位
UCHAR ISendStrB(UCHAR sla,USHORT suba,UCHAR *s,UCHAR no);
// for 24C32/64/128/256
// sla 為 EEPROM的slave 址
// suba 為要寫進數據的地址,大于等于24C32地址是16位的
// *s 為要寫進的數據的頭地址
// no 為要寫進的字節數量,如一次寫進16 bytes,則no=16
此函數用于向EEPROM寫數據,不同的EEPROM 頁編程的大小是不一樣的,大家可以參考datasheet,如24c32一次可寫進16byte 的數據,但必須從每頁的頭地址開始寫
UCHAR ISendStrS(UCHAR sla,UCHAR suba,UCHAR *s,UCHAR no);
//for 24C02/04/08/16/
此函數用于向EEPROM寫數據,suba為8位
UCHAR IRcvStrB(UCHAR sla,USHORT suba,UCHAR *s,UCHAR no);
//for 24C32/64/128/256
此函數用于向EEPROM讀數據,suba為16位
UCHAR IRcvStrS(UCHAR sla,UCHAR suba,UCHAR *s,UCHAR no);
//for 24C02/04/08/16/
此函數用于向EEPROM讀數據,suba為8位
大家學會了上面幾個函數就可以隨意讀寫EEPROM了。
如果想進一步學習上面的函數是怎麼寫出來的,就要參考一下IIC時序了
如大家對著下圖的Start condition和下面的Start_I2c函數就很容易理解了:
/*******************************************************************
Start iic bus
********************************************************************/
void Start_I2c(void)
{
SDA=1; /* send start data signal */
SCL=1;
DelayUs(5); /* wait more than 4.7us*/
SDA=0; /* send start signal */
DelayUs(5); /* wait more than 4.7us*/
SCL=0;
}
是不是很簡單呢?
更多的函數,大家可以下面程序回去研究一下,也可以直接運行于RL78/G13開發板上
每一次讀寫正確,板上的D2 LED會翻轉一次。
——回复可见内容——

受控于上位機的直流電機
視頻:http://v.eepw.com.cn/video/play/id/1963
下面我們基于RL78/R13開發板來做一個用上位機控制直流電機正反轉,加速,減速,暫停的程序。
1、首先我們按下面的原理圖焊接一個H桥电路
從電路上我們可以看出:
當PWM1為高電平,PWM2為低電平時,電流經T2流過直流電機再經T5流到地
當PWM1為低電平,PWM2為高電平時,電流從經T1流過直流電機再經T6流到地
當PWM1,PWM2同時為高或低電平時,電機就可以停轉了
這樣我們就可以實現了直流電機轉向的控制了。
當PWM1為100% Duty,PWM2為50% Duty時,馬達的轉速就減低了。
2、很明顯,要實現不同轉速和轉向的控制,我們需要兩路PWM,我們把PWM1/PWM2分別連接到RG78/G13開發板的P16/TO01和 P31/TO03
因為RG78/G13開發板的UART2連接到UART轉USB上去,所以我們可以很方便的用UART2與上位機進行通訊。
到這里硬件電路就建好了,下面開始軟件開發。
3、為了加快速度,我們用Applilet生成基本代碼
4、系統時鐘設置
設定系統時鐘為32M,如下圖:
為了簡單,關閉WDT,如下圖:
5、設置PWM通道
定義Channel0和Channel2為PWM Master通道,Channel1和Channel3就自動設為Slave通道了,設置如下圖:
設置Master通道Channel0和Channel2的Cycle均為100us,Channel0的設置如下圖,Channel2的設置與Channel0相同:
設置Slave 通道Channel1和Channel3的Duty value均為50%,Channel1的設置如下圖,Channel3的設置與Channel1相同:
6、設置UART2
這次實驗只需要接收命令,所以我把UART2設為僅接收,如下圖:
UART2的參數設置如下圖:
7、點擊”Generate”生成代碼
8、用IAR打開生成的“PWM.eww”文件。
9、在主文件“CG_main.C”定義寄存器,如下圖,藍色框中的代碼是我增加進去的:
10、串口接收代碼編寫:
CG_main.c中定義的寄存器,有兩個CG_serial_user.c這個文件也要用到,要在頭部定義一下,如下:
extern UCHAR DataReceive;
extern UCHAR RXBuffer[2];
11、在CG_serial_user.c中的UART2_ReceiveEndCallback函數增加以下代碼:
藍色部份是我增加的,主要功能是接收到上位機的數據后,先停止UART2接收,然后設置標志位DataReceive,以便主程序處理數據
void UART2_ReceiveEndCallback(void)
{
/* Start user code. Do not edit comment generated here */
UART2_Stop();
DataReceive=1;
/* End user code. Do not edit comment generated here */
}
最后在CG_main.c這個文件里寫一個簡單的測試程序如下:
void main(void)
{
/* Start user code. Do not edit comment generated here */
__low_level_init(); //初始代系統
Direction=0; //定義馬達的初始轉向
MotorDuty=50; //定義馬達的初始轉速
TAU0_Channel3_ChangeDuty(100); //通道3為100% duty輸出
TAU0_Channel1_ChangeDuty(100-MotorDuty); //通道1根據初始化數據輸出
TAU0_Channel0_Start();
TAU0_Channel2_Start(); //啟動PWM模塊
DataReceive=0;
UART2_ReceiveData(RXBuffer, 2); //等待接收上位機的命令,命令為2 byte數據
UART2_Start(); //啟動UART2模塊
while (1U)
{
if(DataReceive==1) //如接收到命令數據,進行如下處理
{
if(RXBuffer[0]=='%' && RXBuffer[1]=='F') // forward command
{
Direction=0;
TAU0_Channel1_ChangeDuty(100);
TAU0_Channel3_ChangeDuty(100-MotorDuty);
}
else if(RXBuffer[0]=='%' && RXBuffer[1]=='B') // backward command
{
Direction=1;
TAU0_Channel1_ChangeDuty(100-MotorDuty);
TAU0_Channel3_ChangeDuty(100);
}
else if(RXBuffer[0]=='%' && RXBuffer[1]=='S') // stop command
{
TAU0_Channel1_ChangeDuty(100);
TAU0_Channel3_ChangeDuty(100);
}
else if(RXBuffer[0]=='%' && RXBuffer[1]=='+') // speed up command
{
MotorDuty +=10;
if(MotorDuty>100)
{
MotorDuty=100;
}
if(Direction==0)
{
TAU0_Channel1_ChangeDuty(100);
TAU0_Channel3_ChangeDuty(100-MotorDuty);
}
else
{
TAU0_Channel1_ChangeDuty(100-MotorDuty);
TAU0_Channel3_ChangeDuty(100);
}
}
else if(RXBuffer[0]=='%' && RXBuffer[1]=='-') // speed down command
{
MotorDuty -=10;
if(MotorDuty<30)
{
MotorDuty=30;
}
if(Direction==0)
{
TAU0_Channel1_ChangeDuty(100);
TAU0_Channel3_ChangeDuty(100-MotorDuty);
}
else
{
TAU0_Channel1_ChangeDuty(100-MotorDuty);
TAU0_Channel3_ChangeDuty(100);
}
}
else
{
NOP();
}
DataReceive=0;
UART2_ReceiveData(RXBuffer, 2);
UART2_Start();
}
}
/* End user code. Do not edit comment generated here */
}
這樣就大功告成了,把程序下載到開發板,打開串口助手開始測試吧
記得把開發板上的J6/J7/J8/J9 接到2-3
通過串口助手發送以下命令進行測試
%F
%S
%B
%+
%-
Campozeng
2012-9-12
本文的PDF文檔和完整代碼從下面鏈接下載
——回复可见内容——
——回复可见内容——
下圖是我接H橋電路和RL78/G13開發板,簡單了點,但可以用的哦

低功耗模式運行測試(HALT & STOP)
本次測試連接P70/KR0 和 P71/KR1至兩個輕觸開關,產生進入和退出低功耗模式運行。
功能:正常模式RL73/G13板上的D2點亮,HALT和STOP模式下D2滅。
可以用萬用表來測試各模式下運行的電流;
首先用Applilet生成基礎代碼,我用KR(鍵盤)中斷來喚醒中斷。
在CG_main.c文件定義以下寄存器作為模式的標志位
UCHAR SystemStatus;
在CG_userdefine.h文件定義以下宏
#define SYSTEM_STOP 3
#define SYSTEM_HALT 2
#define SYSTEM_ON 1
下面一點值得注意:
在設置P70/P71兩個IO pull-high 不然功能不正常,Applilet生成的代碼里沒有設pull-high
在CG_int.c這個文件的Key_Int這個函數里加入以下藍色代碼:
/* Set KR0 pin */
PM7 |= 0x01U;
PU7 |= 0x01U;
/* Set KR1 pin */
PM7 |= 0x02U;
PU7 |= 0x02U;
在CG_int_user.文件里頂部加入寄存器SystemStatus的聲明代碼:
extern UCHAR SystemStatus;
在CG_int_user.文件里寫按鍵中斷函數如下以便控制模式運行:
#pragma vector = INTKR_vect
__interrupt void MD_INTKR(void)
{
/* Start user code. Do not edit comment generated here */
if(P7_bit.no0==0) //KR0
{
if(SystemStatus==SYSTEM_ON)
{
SystemStatus=SYSTEM_HALT;
}
else if(SystemStatus==SYSTEM_HALT)
{
SystemStatus=SYSTEM_ON;
}
}
else if(P7_bit.no1==0) //KR1
{
if(SystemStatus==SYSTEM_ON)
{
SystemStatus=SYSTEM_STOP;
}
else if(SystemStatus==SYSTEM_STOP)
{
SystemStatus=SYSTEM_ON;
}
}
/* End user code. Do not edit comment generated here */
}
寫一個簡單的main函數來進行測試:
void main(void)
{
/* Start user code. Do not edit comment generated here */
__low_level_init();
KEY_Enable();
SystemStatus=SYSTEM_ON;
PU7_bit.no7 = 1;
PM7_bit.no7 = 0;
P7_bit.no7=1; //define the LED on RL78/G13 board
while (1U)
{
if(SystemStatus==SYSTEM_ON)
{
P7_bit.no7=0; //LED on
}
else
{
P7_bit.no7=1; //LED off
if(SystemStatus==SYSTEM_HALT)
{
HALT();
}
else
{
STOP();
}
}
}
/* End user code. Do not edit comment generated here */
}
本試驗代碼在下面鏈接下載:
低功耗模式運行測試(HALT & STOP)代碼
回复
有奖活动 | |
---|---|
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏10分 | |
【我踩过的那些坑】DRC使用位置错误导致的问题被打赏100分 | |
我踩过的那些坑之混合OTL功放与落地音箱被打赏50分 | |
汽车电子中巡航控制系统的使用被打赏10分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏100分 | |
分享汽车电子中巡航控制系统知识被打赏10分 | |
分享安全气囊系统的检修注意事项被打赏10分 | |
分享电子控制安全气囊计算机知识点被打赏10分 | |
【分享开发笔记,赚取电动螺丝刀】【OZONE】使用方法总结被打赏20分 | |
【分享开发笔记,赚取电动螺丝刀】【S32K314】芯片启动流程分析被打赏40分 |