33、基于CACX和R7F0C004M的瑞萨单片机入门教程

代码资源下载:https://download.csdn.net/download/BaoTTing/58444918

一、开发环境介绍

CS+ for CACX: 瑞萨单片机开发环境,已经停止更新,含有图形化配置工具,免费。
CS+ for CC: 瑞萨单片机开发环境,未来主推的开发环境,含有图形化配置工具,收费,适合财力雄厚的开发者。(其实用CACX足以)
IAR for RL78: 瑞萨单片机开发环境,IAR推出的RL78系列的开发环境,寄存器编程,不集成图形化配置工具。
AP4 for RL78_EC:瑞萨单片机独立图形化配置工具,是单独的一个软件,把生成的代码导入到工程里即可。
注1:瑞萨单片机型号有日本区的、中国区的,中国区的一般在开发环境中看不到型号,需要首先导入设备文件才能看到。
注2:本单片机入门教程基于 CS+ for CACX(开发环境) 和 R7F0C004 (MCU型号)进行讲解,为入门解决各种头疼的问题。

二、下载与仿真器的选择

瑞萨单片不像STM32一样内部有boot程序,所以裸机情况下不支持串口下载。IECUBE、E2 Lite 、E1 、E20 、EZ均为瑞萨单片机的下载&仿真器,其中E1功能最多,但也非常昂贵,好几千的价格。E2 Lite是E2的硬件简化版本,网上有很多自己制作的,一个也就卖一二百,建议使用这款,去某宝购买的时候,名字可不是E2 Lite,而是EZ CUBE2,所以花费200左右去某宝买一个EZ CUBE2就可以完成下载和仿真的工作了。(软件中没有EZ CUBE2,只 有E2 Lite,设置仿真器为E2 Lite即可,废话不多说,上图)
在这里插入图片描述

三、CS+ for CACX软件安装

CS+ for CACX安装非常简单,也不需要破解,一直点同意&下一步即可完成安装,这里不在赘述。
如需软件安装包和MCU支持包,可以去瑞萨官网自行下载、或者加全国大学生电子交流QQ群649692007下载、5积分下载。
在这里插入图片描述
MCU支持包安装方式如下:
在这里插入图片描述
CSPlus_CACX_Package_V40500.7z <===点击此处下载CS+ FOR CACX,仅需5积分

R7F0C001_002_003_004_019_MCU设备文件.zip <===点击此处下载MCU设备文件,仅需5积分

四、新建工程

说明:但凡通过添加支持包的MCU型号在软件中都不支持图形化配置,需要用AP4生成后导入,由于R7F0C004M和R5F10WMG几乎完全一样,R7F0C004M仅是在R5F10WMG的基础上阉割了一两个外设而已,为了使用CACX内部的集成配置工具,这里使用R5F10WMG进行建立工程,多出的外设不配置,直接关闭即可。(以下是特别全乎的建工程模板的教程,可以避免很多CACX软件BUG带来的问题—原创哦)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

至此,工程建立完成,建议按照图片教程配置,会省去很多不必要的麻烦(不要感谢我,我只会个helloworld,收藏一下我吧)
CACX软件只能函数跳转,不能变量跳转,只能用查找的方式进行变量跳转,或者使用外部编辑器编辑**推荐vscode。

五、开发板选择与原理图分享

MCU最小系统电路
在这里插入图片描述
四线下载电路
在这里插入图片描述
在这里插入图片描述
完整开发板原理图和PCB请加全国大学生电子交流QQ群获取:649692007

六、定时器(基于状态机制,下同)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//根据BaseTimerCount计算差值函数
uint32_t  CheckTimer(uint32_t Timer) 
{
    if(BaseTimerCount > Timer){ return(BaseTimerCount - Timer); }
    else{ return ~(Timer - BaseTimerCount) + 1; }
}
//示例函数:实现1s、2s、3s周期的定时
int main(void)
{
    uint32_t timerx_1s;
    uint32_t timerx_2s;
    uint32_t timerx_3s;
    R_TAU0_Channel0_Start();//定时器初始化
    timerx_1s = BaseTimerCount;
    timerx_2s = BaseTimerCount;
    timerx_3s = BaseTimerCount;
    while(1U)
    {
       	if(CheckTimer(timerx_1s)>1000)
       	{
		    timerx_1s = BaseTimerCount;
		    //..........   <---1s周期任务
		}
		if(CheckTimer(timerx_2s)>2000)
       	{
		    timerx_2s = BaseTimerCount;
		    //..........   <---2s周期任务
		}
		if(CheckTimer(timerx_3s)>3000)
       	{
		    timerx_3s = BaseTimerCount;
		    //..........   <---3s周期任务
		}
    }
}

七、LED流水灯

在这里插入图片描述

//示例函数:实现1s、2s、3s周期的定时
int main(void)
{
    uint32_t timerx_1s;
    R_TAU0_Channel0_Start();//定时器初始化
    timerx_1s = BaseTimerCount;
    while(1U)
    {
       	if(CheckTimer(timerx_1s)>1000)
       	{
		    timerx_1s = BaseTimerCount;
		    P1^=0x01;                //LED 1s翻转一次
		}
    }
}

八、串口初始化

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
  * @brief : Uart0字节发送函数
  * @param : 
  *	@u8Data: 要发送的数据
  * @note  : 非中断方式
  * @retval: 是否超时
  */
uint8_t Uart0_SendByte(uint8_t u8Data)
{
   uint16_t timesout = 0;
   STMK0 = 1U;
   STIF0 = 0U;
   TXD0 = u8Data;
   while(STIF0 == 0U)
   {
      timesout++;
      if(timesout>50000){
      	break;
      }
   }   
   STIF0 = 0U;
   return (timesout>5000)?1:0;
}
volatile uint8_t Uart0Rx_Buf[128];  
/**
  * @brief : Uart0任务函数
  * @param : 无
  * @note  : 收到什么数据,打印什么数据
  * @retval: 无
  */
typedef enum SAUTASK //TaskState-Enum
{
   SauTask_Init = 0,   //Init----Mode
   SauTask_Idle,       //Idle----Mode
   SauTask_Rev,        //Receive-Mode
   SauTask_NoExBat,    //NoExBat-Mode
   SauTask_Stop,       //Stop----Mode
}SauTaskState_Type;
extern volatile uint16_t  g_uart0_rx_count;
SauTaskState_Type  SauTaskState0;  
void Sau0_Run_Task(void)
{
   uint8_t i = 0;
   static uint8_t sau_first_flag = 0;
   static uint32_t sau_timer = 0;
   static uint8_t last_rx_count = 0xFF;  
   switch(SauTaskState0)
   {
      case SauTask_Init:
        last_rx_count = 0xFF;
	R_UART0_Start();
	R_UART0_Receive(Uart0Rx_Buf,128);
	SauTaskState0 =  SauTask_Idle;
      break;
      case SauTask_Idle:
        if(g_uart0_rx_count>1)
	{
           last_rx_count = (uint8_t)(g_uart0_rx_count&0x0FF);
           sau_timer = BaseTimerCount;
	   SauTaskState0 = SauTask_Rev;
	}
      break;      
      case SauTask_Rev:
        if(g_uart0_rx_count!=last_rx_count)
	{
	   last_rx_count = (uint8_t)(g_uart0_rx_count&0x0FF);
           sau_timer = BaseTimerCount;
	}
	else
	{
	   if(CheckTimer(sau_timer)>TIME_5MS)
	   {  
	      for(i=0;i<last_rx_count;i++)
	      {
		  Uart0_SendByte(Uart0Rx_Buf[i]);
	      }
	      sau_timer = BaseTimerCount;
	      R_UART0_Receive(Uart0Rx_Buf,128); 
              SauTaskState0 = SauTask_Idle;
           }
	}	      
      break;  
      case SauTask_NoExBat:
        R_UART0_Stop();
      break;
      default:break;
   }
}
//主函数
int main(void)
{
    R_TAU0_Channel0_Start();//定时器初始化
    while(1U)
    {
        Sau0_Run_Task();
    }
}

九、串口printf

   /*注意:由于单片机是16位的,遵循双字节对齐,所以数字项最大值为65535,超过的部分将被强制转化*/
   #define __out_putchar  Uart0_SendByte //需要用户修改
   /*--以下部分直接拷贝即可--*/
   #define MAX_NUMBER_BYTES  64
   typedef char *  va_list;
   #define _INTSIZEOF(n)   ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
   #define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) + 6 )               //v = 第一个传入参数*,ap = 第二个传入参数的地址
   #define va_arg(ap,t)    ( *(t *)( ap=ap + _INTSIZEOF(t), ap - _INTSIZEOF(t)) ) //返回当前参数地址,ap指向下一个参数  
   #define va_end(ap)      ( ap = (va_list)0 )
   unsigned char hex_tab[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
   static int outc(int c) 
   {
      __out_putchar((unsigned char)c);
      return 0;
   }
   static int outs (const char *s)
   {
      while (*s != '\0')	
	 __out_putchar(*s++);
      return 0;
   } 
   static int out_num(long n, int base,char lead,int maxwidth) 
   {
      unsigned long m=0;
      char buf[MAX_NUMBER_BYTES], *s = buf + sizeof(buf);
      int count=0,i=0;
      *--s = '\0';
      if (n < 0){m = -n;}else{m = n;}//m=|n|
      do{
	  *--s = hex_tab[m%base];
	  count++;
      }while ((m /= base) != 0);
      if( maxwidth && count < maxwidth){
	for (i=maxwidth - count; i; i--)	
	    *--s = lead;	
        }
	if (n < 0)*--s = '-';
	return outs(s);
   } 
   static int my_vprintf(const char *fmt, va_list ap) 
   {
      char lead = ' ';
      int  maxwidth = 0;
      for(; *fmt != '\0'; fmt++)
      {
	 if (*fmt != '%') {outc(*fmt);continue;}//continue:只结束本次循环
	 lead=' ';maxwidth=0;		
	 fmt++;	
	 if(*fmt == '0'){     
	    lead = '0';fmt++;	
	 }
	 while(*fmt >= '0' && *fmt <= '9'){
	    maxwidth *=10;
            maxwidth += (*fmt - '0');
            fmt++;
	 }
	 switch (*fmt) {
	    case 'd': out_num(va_arg(ap, int),10,lead,maxwidth); break;
	    case 'o': out_num(va_arg(ap, unsigned int),  8,lead,maxwidth); break;				
	    case 'u': out_num(va_arg(ap, unsigned int), 10,lead,maxwidth); break;
	    case 'x': out_num(va_arg(ap, unsigned int), 16,lead,maxwidth); break;
	    case 'c': outc(va_arg(ap,int)); break;		
	    case 's': outs(va_arg(ap, char *)); break;		  						
	    default: outc(*fmt);break;
	}
      }
      return 0;
   }
   int printf(const char *fmt,...) 
   {
      va_list ap;
      va_start(ap,fmt);
      my_vprintf(fmt, ap);
      va_end(ap);
      return 0;
   }
   int my_printf_test(void)
   { 
      printf("全国大学生电子交流群:649692007\n\r") ;	
      printf("test char =%c,%c\n\r", 'A','a') ;	      
      printf("test decimal number =%d\n\r",12345);   /*注:max=65535*/
      printf("test decimal number =%d\n\r",-12345);  /*注:max=65535*/	
      printf("test hex number =0x%x\n\r",0x55aa);    /*注:max=65535*/	
      printf("test string =%s\n\r","www.100ask.org");/*注:max=65535*/
      printf("num=%08d\n\r",12345);                  /*注:max=65535*/
      printf("num=%8d\n\r",12345);                   /*注:max=65535*/
      printf("num=0x%08x\n\r",0x2345);               /*注:max=65535*/
      printf("num=0x%8x\n\r",0x2345);                /*注:max=65535*/
      printf("num=0x%02x\n\r",0x1);                  /*注:max=65535*/
      printf("num=0x%2x\n\r",0x1);                   /*注:max=65535*/
      printf("num=%05d\n\r",0x1);                    /*注:max=65535*/
      printf("num=%5d\n\r",0x1);                     /*注:max=65535*/
      return 0;    
   }

十、ADC电压采集

十一、ADC+DMA

十二、PWM呼吸灯

十三、IIC驱动EEPROM

十四、RTC实时时钟

十五、LCD控制器

十六、按键

在这里插入图片描述
欢迎加入全国大学生电子交流QQ群:649692007
在这里插入图片描述

  • 9
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 瑞萨r7f0c014是一款微控制器,其程序在线升级是指在该微控制器上运行的程序可以通过网络或其他通信手段进行升级。 程序在线升级具有许多优点。首先,它可以使设备的功能更加灵活和易于更新,无需将设备连接到计算机或其他外部设备。只需要通过网络连接,可以将新的功能或修复bug的程序推送到设备上。这样,用户可以无需更换硬件即可享受到设备的新功能,提高了设备的使用价值。 其次,程序在线升级也为设备提供了更好的安全性。因为在设备生命周期中,可能会发现一些安全漏洞或缺陷,这些问题可以通过在线升级来修复。设备制造商可以及时推送补丁程序,以解决已发现的漏洞,提高设备的安全性。 此外,程序在线升级也可以为设备制造商提供更好的用户支持。当用户遇到问题或反馈时,设备制造商可以通过在线升级来提供解决方案。通过在线更新,制造商可以及时修复错误或添加新功能来满足用户的需求,提高用户体验。 总之,瑞萨r7f0c014程序在线升级是一种方便、灵活、安全和高效的策略,为设备制造商和用户带来许多好处。它使得设备的持续更新和改进成为可能,为用户提供更好的功能体验和安全性保障。 ### 回答2: 瑞萨R7F0C014是一款微控制器芯片,具有在线升级程序的功能。在线升级程序是指通过网络连接将新的软件或固件升级包传输到芯片中进行更新的操作。 使用瑞萨R7F0C014的在线升级程序功能,可以方便地将新的功能、修复错误或改进性能等更新应用到芯片中。在线升级程序可以通过网络连接传输,通过与主机设备的通信接口(如UART、USB等)与瑞萨R7F0C014芯片进行数据交互,实现程序的下载和更新。 在线升级程序具有以下优点: 1. 方便快捷:不需要将芯片从主机设备中移除,只需通过网络连接即可进行程序的在线升级,无需繁琐的拆卸和安装流程。 2. 灵活性:在线升级程序可以根据需求进行灵活的更新,可以根据实际情况选择是否进行升级,以满足不同的应用需求。 3. 效率高:在线升级程序可以在繁忙的生产环境中实现迅速的软件或固件更新,节省了拆装芯片的时间和劳动力。 但同时也需要注意一些问题: 1. 安全性:在线升级程序需要保证数据的安全性,防止非法入侵或篡改。 2. 稳定性:在线升级过程中需要保持良好的网络连接以及稳定的电源供应,以防止升级失败或数据丢失。 综上所述,瑞萨R7F0C014具有在线升级程序的功能,通过网络连接可以方便地将新的软件或固件升级包传输到芯片中进行更新。在线升级程序具有方便快捷、灵活性和高效率的优点,但需要注意安全性和稳定性的问题。 ### 回答3: 瑞萨R7F0C014是一款微控制器芯片,支持程序在线升级的功能。在线升级是指无需将设备拆解或更换芯片,通过网络连接直接对芯片的软件进行升级。瑞萨R7F0C014采用了成熟的硬件设计和软件支持,使得在线升级操作更加方便和高效。 在进行瑞萨R7F0C014的程序在线升级时,首先需要将芯片连接到网络,可以通过以太网、WiFi或蓝牙等常用的通信方式。然后,使用相应的软件工具来管理和控制升级过程。这些软件工具通常提供了简单易用的图形界面,使得用户能够轻松选择要升级的文件和目标设备。 在线升级过程中,软件工具会先验证升级文件的完整性和有效性,以确保升级过程的安全和稳定性。然后,软件工具会将升级文件逐步传输到目标设备的存储器中,并进行相应的数据校验。在传输完成后,芯片会自动重启,并加载新的程序。 瑞萨R7F0C014的在线升级功能非常实用,因为它可以帮助用户快速修复漏洞、加入新功能以及改进现有功能。与传统的手动删除和替换芯片相比,在线升级更加方便且成本更低。此外,在线升级还可以减少设备停机和用户的不便,提高了整个升级过程的效率。 总之,瑞萨R7F0C014支持程序在线升级,可以通过网络连接实现快速、安全和高效的升级操作,为用户带来便利和新的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值