资讯详情

【复旦微】国产MCU学习(持续更新)

复旦微MCU学习笔记

  • 写在前面
  • 准备工作
  • 外设清单
    • 1.UART串口
      • 串口对应引脚
    • 2.ADC
      • 采样通道对应引脚
  • 项目功能
    • 1.ADC采样(以MQ-2为例)
    • 2.单总线通信(以DS18B20为例)
      • ①STM32F103C8T6代码调试
        • 1.用于传感器的引脚初始化:
        • 2.传感器复位检查(检查是否有传感器)
        • 3.启用传感器温度转换
        • 4.读数
      • ②FM33LC046N代码移植

写在前面

??1.帖子原因:由于巧合,使用复旦微芯片嵌入式设计,复旦微论坛有很多信息也有很多沟通帖子,但他们的发展会遇到很多问题,帖子是记录他们的学习过程,也方便检查相关信息,目的是学习使用。 ??2.芯片选择: ??①之前参加过复旦微电赛,比赛推荐的芯片是FM33LG048,可惜当时市场上没有可靠的官方开发板,所以选择了FM33LC046N复旦微代码逻辑首先适应。现在开发下一个项目涉及芯片的选择,手头正好有FM33LC046N所以最后选择了开发板FM33LC046N(市场似乎已经存在了FM33LG该系列开发板已售出,可根据需要选择,不必选择LC系列)。 ??②此外,我以前参加过嵌入式比赛,赞助商也参加过比赛RTThread,这是一个国内嵌入式操作系统,配备了独立编程的软件,感觉更方便,由于时间和精力有限,不能深入学习操作系统,在其支持RTThread Studio复旦微板卡在软件中还没有找到,也许双方还没有正式合作,但在复旦微论坛上,有人加入了RTThread操作系统的LC系列板卡的bsp包,也就是说,LC可以在板子上跑RTThread虽然由于时间和精力问题,操作系统不能真正将国内操作系统投入应用,但选择LC该系列的开发板也有开发空间。

准备工作

??FM33LC046N开发板有很多针(开发板都是这样),但是开发板是通过改变的Type-B串口实现5V供电,板载线性降压芯片降压3.3V,有几个跳线帽必须接才能实现上述功能,即实现板卡的正常供电: 在这里插入图片描述 ??此外,我们经常使用串口和调试LED灯,串口后面再说,LED还需要连接一个端子: ??对应的实物是用跳线帽连接这些位置: ??有点看不清楚,在板的左边,图中用白色圆圈出来。

外设清单

1.UART串口

串口对应引脚

引脚 UART 符号 功能
PA2、PA13 UART0 UART0_RX 数据接收
PA3、PA14 UART0_TX 数据发送
PC2、PB13 UART1 UART1_RX 数据接收
PC3、PB14 UART1_TX 数据发送
PA0、PB2 UART4 UART4_RX 数据接收
PA1、PB3 UART4_TX 数据发送
PC4、PD0 UART5 UART5_RX 数据接收
PC5、PD1 UART5_TX 数据发送

2.ADC

采样通道对应引脚

??FM33LC046N共有12个外部采样通道和4个内部特殊通道(TS、Vref、OPA1、OPA2)

通道 引脚 说明
ADC_IN0 PC9 快速通道
ADC_IN1 PC10 快速通道
ADC_IN2 PD11 快速通道
ADC_IN3 PD0 快速通道
ADC_IN4 PD1 快速通道
ADC_IN5 PD2 快速通道
ADC_IN6 PA13 快速通道
ADC_IN7 PA14 快速通道
ADC_IN8 PC7 慢速通道
ADC_IN9 PC8 慢速通道
ADC_IN10 PA15 慢速通道
ADC_IN11 PC6 慢速通道

项目功能

1.ADC采样(以MQ-2为例)

硬件接法: 1.MQ-2传感器 ??①5V在引脚板上VCC5(Type-B接口附近,跳线帽上的针); ??②AO引脚开发板PC9引脚; ??③GND接开发板GND 2.USB-TTL(串口) ??接开发板UART0(PA13接TXD,PA14接RXD),串口5V引脚悬空,3.3V短接引脚跳线帽VCC。 代码存储目录(本地电脑): ??E:\MCU\FM33\Jiedian\ADC

??使用的传感器是MQ-2.是最基本的烟雾传感器(对可燃气体也有反应),检查数据显示FM33LC046N好像只有一个1Msps 12bit的ADC,正常情况下,电压表测量400mA,采样串口输出406mA,用打火机测试(丁烷气体)后,AO由于动态变化,采样电压升高难读,试验结果如下表所示:

实测值(mA) 采样值(mA)
400 406
441 449
953 961
1492 1518
1555 1560

  整体误差可以说是非常小了,误差基本在10mA以内,上表还包含了人眼测量的误差,可以说表现让人很满意。   有兴趣的可以去试一下用STM32F103C8T6芯片去试一下,例程很多,我测试过了,包括所谓的ADC上电校准,包括Vref校准在内我都试过了,低电压的时候误差在100mA左右,高电压的时候的误差简直不能看。不是针对最小系统板,懂得都懂,STM32F103C8T6功能很强大,资料也很多,是我嵌入式入门的板子,就事论事,这个ADC采样是真的拉跨,网上有人说对精度有要求的话可以外接ADC,我比较懒……

2.单总线通信(以DS18B20为例)

  本来以为这是很简单的事,没想到这反而是最让我头疼的,下面记录一下调试步骤:

①STM32F103C8T6代码调试

  众所周知,STM32的最大优势是它资料多,DS18B20的代码直接就有现成的,可以参考正点原子的代码即可,我这边整理一下主要步骤:

1.传感器用到的引脚初始化:

  这里使能的PB0引脚,初始化为推挽输出模式,初始化完成之后引脚置高电平:

2.传感器复位检验(检查有无传感器)

  ①传感器复位

//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT(); 	//SET PB0 OUTPUT
	DS18B20_DQ_OUT=0; 	//拉低DQ
	delay_us(750);    	//拉低750us
	DS18B20_DQ_OUT=1; 	//DQ=1 
	delay_us(15);     	//15US
}

  这里的DS18B20_IO_OUT和后面遇到的DS18B20_IO_IN是STM32特有的位带操作,OUT就是把对应的引脚切换为开漏输出模式,IN就是把对应的引脚切换为上拉/下拉输入模式:

//IO方向设置
#define DS18B20_IO_IN()  {GPIOB->CRL&=0XFFFFFFF0;GPIOB->CRL|=8<<0;}
#define DS18B20_IO_OUT() {GPIOB->CRL&=0XFFFFFFF0;GPIOB->CRL|=3<<0;}

  CRL低四位赋值8即如下图(1 0 0 0):   CRL低四位赋值3即如下图所示(0 1 1 0):   根据下图手册中的定义可以解读出配置的对应模式是什么,前文写了,分别是开漏输出模式和上拉/下拉输入模式。   这里因为使用的是PB0引脚所以是CRL,如果是8~15引脚,对应的CRH寄存器,原理都是一样的。   ②传感器检查   根据DS18B20官方手册中所示,传感器在接收到MCU发送的初始化信号后,会拉低60~240us,然后拉高。   因此,代码中先将PB0置为上拉输入模式,然后读取PB0引脚的电平,如果没接传感器,那么引脚在电阻拉高之后将不会被拉低,代码将会在第一个while循环内循环至retry=200,最终返回1,表示未检测到DS18B20传感器;在检测到第一阶段的低电平之后,传感器会再次拉高,代码中通过第二个while循环检测,当传感器并没有拉高时,retry会循环累加至240,同样返回1,表示未检测到传感器,反之则表示传感器初始化成功。

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();	//SET PB0 INPUT	 
	while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
	while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}

3.启用传感器温度转换

  以上是相当于传感器初始化,后面的流程(即步骤3、4)每进行一次读取温度,都需要执行,因此放在了while主循环内。

//开始温度转换
void DS18B20_Start(void) 
{   						               
	DS18B20_Rst();	   
	DS18B20_Check();	 
	DS18B20_Write_Byte(0xcc);	// skip rom
	DS18B20_Write_Byte(0x44);	// convert
} 

  这里可以看出来前面依然是初始化流程,不同的是发送了0xcc和0x44至传感器,作用是启动温度转换:   DS18B20传感器的手册中说明了,0xcc指令的作用就是同时寻址总线上所有设备,后半句说了,主机在0xcc指令后接一个0x44指令可以使总线上的所有DS18B20传感器同时执行温度转换。   Write_Byte函数如下所示,需要结合DS18B20传感器读写时序图看:首先将引脚配置为开漏输出模式,取需要发送的数据的最低位赋值给testb,如果是1,先拉低总线电平>1us,然后拉高,如果是0,拉低最大值60us,然后拉高:

//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
{             
	u8 j;
	u8 testb;
	DS18B20_IO_OUT();	//SET PB0 OUTPUT;
	for (j=1;j<=8;j++) 
	{
		testb=dat&0x01;
		dat=dat>>1;
		if (testb) 
		{
  			DS18B20_DQ_OUT=0;	// Write 1
  			delay_us(2);                            
  			DS18B20_DQ_OUT=1;
  			delay_us(60);             
		}
		else 
		{
  			DS18B20_DQ_OUT=0;	// Write 0
  			delay_us(60);             
  			DS18B20_DQ_OUT=1;
  			delay_us(2);                          
		}
	}
}

  DS18B20传感器读写时序图如下所示:

4.读数

  首先还是初始化流程,然后发送了0xcc、0xbe指令,然后就是MCU读取存放了DS18B20温度数据的寄存器:

DS18B20_Rst();
DS18B20_Check();	 
DS18B20_Write_Byte(0xcc);	// skip rom
DS18B20_Write_Byte(0xbe);	// convert	    
TL=DS18B20_Read_Byte(); 	// LSB   
TH=DS18B20_Read_Byte(); 	// MSB 

  这里我一开始很好奇,为什么每次都要先初始化一下,初始化之后温度转换的数据是不是就没了?然后在传感器说明书中找到了如下说明,意思就是,主机每次需要和DS18B20通信发送相应指令时都需要执行一次初始化流程:   0xbe指令的作用是读取暂存器中的数据,数据传输从最低有效位0开始,直到第九个字节被读取。   此外需要注意只有在总线上只有一个DS18B20传感器的时候,0xcc指令后面可以直接跟一个0xbe指令。   Read_Byte函数如下所示,就是简单的一位一位读取然后赋值给dat:

//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)     
{        
	u8 i,j,dat;
	dat=0;
	for (i=1;i<=8;i++) 
	{
    	j=DS18B20_Read_Bit();
    	dat=(j<<7)|(dat>>1);
	}						    
	return dat;
}

  Read_Bit函数如下所示,这里就需要结合传感器手册给出的时序图来看了,首先读取数据需要先将总线拉低至少1us,这里先将引脚配置为开漏输出,然后拉低总线2us,然后恢复总线至高电平。   这时候如果DS18B20传感器是数据是0,DS18B20会将总线拉低最后再拉高,否则会使总线一直保持为高。   因此先将引脚配置为上拉输入模式,延时12us之后(这里为什么是12us呢,大概就是下图中主机发送指令的时长为15us,前面拉低延时过2us了,这里设置为12us),然后读取总线数据,如果为低电平就是0,反之就是1:

//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 	 
{
	u8 data;
	DS18B20_IO_OUT();	//SET PB0 OUTPUT
	DS18B20_DQ_OUT=0; 
	delay_us(2);
	DS18B20_DQ_OUT=1; 
	DS18B20_IO_IN();	//SET PB0 INPUT
	delay_us(12);
	if(DS18B20_DQ_IN)data=1;
	else data=0;	 
	delay_us(50);           
	return data;
}

②FM33LC046N代码移植

标签: 300pa2pa传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台