单片机/MCU论坛
直播中

刘方南

12年用户 231经验值
擅长:可编程逻辑 模拟技术 测量仪表 接口/总线/驱动 控制/MCU
私信 关注
[讨论]

【敏矽微ME32G070开发板免费体验】之原厂2812测试例程解析

经过几天的学习,对ME32开发有了一些基础认识,所以咱们在这儿抛砖引玉。通过边学习边解析的方式让大家更容易了解这款芯片:
微信截图_20241224224821.png

例程实现的是8路全彩LED 点亮,且循环渐变很是迷幻的效果~
在这儿夸夸中文手册,确实方便了不少;如下的GPIO,一目了然,不过相比STM32,这里没有IO口速度配置,换句话说功耗应该会高一点吧??gpio.png

下面是例程,咱们开始分析:

#define MAX_LIGHT_NUMBER 8  //串联的LED灯数量

                              // R   G    B//
__align(4) uint8_t org_rgb[3]={0xFF,0x0,0x0}; //定义一个起始数据,对应一颗灯的RGB3个8位数据
__align(4) uint8_t rgb[MAX_LIGHT_NUMBER][3]; //每颗灯下都有三组数据
uint32_t * rgbptr;
uint32_t * rgbendptr;

uint8_t start_color=0;

uint32_t data_index=0;

int main(void)
{
	SystemInit ();
	
//	//config pll output to 72M
//	SYS_PLL_Config(HSI_CLK,72000000);
//	//main clock switch to external PLL output 72M
//	SYS_SelectMainClkSrc(PLL_CLK);
	
	PB15_INIT(PB15_BTIM0_MAT0);	//初始化PWM输出口
	PC12_INIT(PC12_BTIM0_MAT0);//一个备用输出口可外接2812
	
	//初始化定时器0,产生us级通信时钟
	BTIM_Init(BTIM0, 16000000); //16Mhz,需比主频低
	BTIM_ConfigPWMDataSift(BTIM0, 20,  5, 20,  15);//800Khz,占空比0->25%,占空比1->75%
	NVIC_EnableIRQ(BTIM0_IRQn);//使能定时器0中断

	//初始化定时器1
	BTIM_Init(BTIM1, 10000); //10Khz定时器
	BTIM_ConfigMatch1(BTIM1, 1000, TIM_MATCH_RESET_COUNTER|TIM_MATCH_TRIGGER_INT); //10ms触发中断
	NVIC_EnableIRQ(BTIM1_IRQn);//使能定时器1中断

	TIM_START(BTIM1);	//定时器启动


	//配置两个开发板上的LED IO口为输出,由于IO口默认初始化后为0,所以不用单独配置写0操作
	PB->DIR_b.DIR10  =0x1;
	PC->DIR_b.DIR4  =0x1;
	
	
	while(1)
	{
		//togglre PB10 output
    //PB->NOT_b .NOT10 =1;//翻转IO电平
		PB->OUT_b.OUT10=1; //写1,测试用
		SYS_Delay(0xFFFF);
		PB->OUT_b.OUT10=0; //写0,测试用
		SYS_Delay(0xFFFF);
	}
}


//定时器0负责产生时序
void BTIM0_IRQHandler(void)
{
	rgbptr=BTIM_DataSiftInt(BTIM0, rgbptr,  rgbendptr);
	//清除BTIMER1中断标志
	BTIM_ClearIntFlag(BTIM0);	
//	PB->NOT_b .NOT10 =1;
}

//定时器1负责更新发送的数据
void BTIM1_IRQHandler(void)
{
	uint32_t i;
	switch (start_color)//数据移位渐变效果
	{
		case 0: //r->g
			org_rgb[0]=org_rgb[0]-51;//红色变暗
			org_rgb[1]=org_rgb[1]+51;//绿色变亮
			if (org_rgb[1]==0xFF)    //循环到绿色为FF时切换
				start_color=1;
			break;
		case 1: //g->b
			org_rgb[1]=org_rgb[1]-51;//绿色变暗
			org_rgb[2]=org_rgb[2]+51;//蓝色变亮
			if (org_rgb[2]==0xFF)    //循环到蓝色为FF时切换
				start_color=2;
			break;
		case 2: //b->r
			org_rgb[2]=org_rgb[2]-51;//蓝色变暗
			org_rgb[0]=org_rgb[0]+51;//红色变亮 
			if (org_rgb[0]==0xFF)    //循环到红色为FF时切换
				start_color=0;
			break;
	}
	for (i=MAX_LIGHT_NUMBER-1;i>0;i--)//将上一课灯的数据移动到下一颗
	{
		rgb[i][0]=rgb[i-1][0];
		rgb[i][1]=rgb[i-1][1];
		rgb[i][2]=rgb[i-1][2];
	}
	rgb[0][0]=org_rgb[0]; //重新赋值数据
	rgb[0][1]=org_rgb[1];
	rgb[0][2]=org_rgb[2];
	rgbptr=(uint32_t *)rgb; //记录数据首地址
	rgbendptr=rgbptr+((MAX_LIGHT_NUMBER*3)>>2); //记录循环长度
	if ((MAX_LIGHT_NUMBER*3)&0x3) 
		rgbendptr++;
	rgbptr=BTIM_StartDataSift(BTIM0, rgbptr,  rgbendptr);//启动数据转换

	BTIM_ClearIntFlag(BTIM1);//清除中断1的标志
	PC->NOT_b .NOT4 =1; //翻转一个IO,可查看是否运行
}

依据以上注释,不知道理解是否正确呢?我们同时外挂一个彩色LED灯带,将洪定义MAX_LIGHT_NUMBER 改为50,照样驱动稳稳的!22.jpg

这里咱们做一下输出时序的波形测试,可看到单总线的高低电平情况:
44.jpg

以及定时器0的IO口翻转波形:
33.jpg

更多回帖

发帖
×
20
完善资料,
赚取积分