/*****蓝桥杯嵌入式总结心得***/

①基于十二届试题

Led引脚要在cubmx中初始化,注意不要忘记PD2控制的锁存器。 为了避免led和lcd引脚冲突,可以封装如下函数:

void LED_disp(unsigned char led_dsp) 
{
         //熄灭
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
	
	HAL_GPIO_WritePin(GPIOC,led_dsp<<8,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

加入让LED1亮则写入(0x01),LED2对应(0x02),LED3对应(0x04),LED4对应(0x08)

LED5(0x10),LED2对应(0x20),LED3对应(0x40),LED4对应(0x80).

注:如果同时想让若干个灯亮,则要进行或运算再写入。

 ②对于数据的接收是定长数据,我采用的是串口接收空闲中断+DMA。具体使用方法可看我的另一篇文章http://t.csdnimg.cn/6DRbw

数据发送时我采用的是阻塞式发送,如果我们要发送的数据过长,注意将等待时间加长,否则会出现数据发送不全的现象!

char text[18];
sprintf(text,"%s:%s:%d:%.2f",cars[i].car_Leixing,cars[i].car_ID,packing_time,packing_fare); 	 
 HAL_UART_Transmit(&huart2,(uint8_t *)text,sizeof(text),50);

③本届试题串口接收数据和对数据的处理是一个重难点。要想方便的处理数据。就不可避免地要会使用一些字符串处理函数。本次使用到的一些如下:

  1.     int atoi (const char * str);其原型定义在stdlib.h头文件中。将数字字符串转换为整数。转换后的值不可超出int可表示的范围。
  2. Strlen()函数获取字符串长度,从字符首地址开始遍历,以‘\0’为结束标志,计算的长度并不包含‘\0’.. 当字符‘a’,'b','c'三个字符依次存放在arr数组中,并没有储存'\0',而strlen()函数只有遇到‘\0’才会停止,故会返回一个随机值。因此这点我们要注意!!头文件:string.h
  3. sizeof()是操作符,当参数是一个类型或者变量,返回值为该变量类型的实际大小,比如int型占4个字节,float型占四个字节。sizeof(int)返回值为4.sizeof(2)(因为2是整形)返回值为4表示占四个字节。当参数为一个静态数组,sizeof()返回数组长度。sizeof()不能返回动态数组的长度。sizeof()还可以将函数作为参数。如: short h();  sizeof(  h()  );返回值为2.
  4. 【int strcmp(char *str1, char *str2)】

        strcmp比较两个字符串的大小,一个字符一个字符比较,按ASCLL码比较标准规定:
        第一个字符串大于第二个字符串,则返回大于0的数字
        第一个字符串等于第二个字符串,则返回0
        第一个字符串小于第二个字符串,则返回小于0的数字

  1.      4.  strcpy()是覆盖拷贝,

        将source全覆盖拷贝到destination,会把’\0’也拷过去,且必须考虑destination的空间够不够
(destination的空间必须>=source的空间)

  1.  5. strcat()追加拷贝,追加到目标空间后面,目标空间必须足够大,能容纳下源字符串的内容

6.字符串sscanf()函数

int sscanf(const char *str,const char *format,...);
str:需要解析的字符串
format:格式控制字符串
...:可变参数,用于存放解析出来的值
返回值:成功则返回解析的成功数量,失败返回-1

:从一个字符串中提取字符串、浮点数、整数等值,并将其保存到指定的变量中。

例:char str[]="123 4.56 hello";

int x; float y; char z[20];

sscanf(str,"%d %f %s",&x,&y,z);

得:x=123  y=4.560000 z=‘hello’

7、sprintf()函数:和printf用法几乎一样,只不过打印地点不同。前者打印到字符串中,后者在命令行上输出。

sprintf(s,"%d",123) //把整数123打印成一个字符串保存在s中
sprintf(s,"%8d",123) //指定宽度,不足左边补空格(右对齐)
sprintf(s,"%-8d",123) //指定宽度,左对齐
sprintf(s,"%x",123) //把整数123以十六进制保存在s中
sprintf(s,"%04x",123) //把整数123以十六进制保存在s中,左边补0等宽为4的模式
sprintf(s,"%f",0.123) //把浮点数打印成一个字符串保存在s中,默认六位小数
sprintf(s,"%2.3f",0.123) //    "m.nf"表示:宽度为m,保留n位小数

④对于停车时间的计算,我只能进行粗略的计算。希望如果有人会的话分享在评论区。

⑤对于汽车的信息有很多,我采用了结构体进行保存。关于结构体我有如下收获:

1、结构体可以直接进行赋值:

struct Point {
    int x;
    int y;
};

int main() {
    Point p1 = {1, 2};
    Point p2;

    // 直接赋值
    p2 = p1;

    // 现在p2的成员等于p1的成员
    // 所以p2.x == 1, p2.y == 2
    return 0;
}

2、当车出库时,不要忘记将该车之后的车往前提,以保证链接。同时防止结构体数组越界,如下操作

//出停车厂后,要保证结构体数组的连贯性,将i后面的信息向前移一个
	uint8_t t;
	for(t=i;t<7;t++) //不要越界
	{
		cars[t]=cars[t+1];
	
	}

//同时保证车辆--,停车厂总数量--
	if((strcmp(Leixing , "CNBR")==0))
	{
		CNBR_num--;
		IDLE_num++;
	}
	if(strcmp( Leixing ,"VNBR")==0)
	{
		VNBR_num--;
		IDLE_num++;
	}

3、结构体的初始化

参考该文章http://t.csdnimg.cn/8vMkL

假设我们有

struct Student
{
  long id;
  char name[20];
  char sex;
}
struct Student a={0};

其相当于a.id=0;a.name=“”;a.sex=‘/0x0’。
仅仅对其中部分的成员变量进行初始化,要求初始化的数据至少有一个,其他没有初始化的成员变量由系统完成初始化,为其提供缺省的初始化值。各种基本数据类型的成员变量初始化缺省值如表


数据类型
缺省初始化值
Int                   0
Char                ‘/0x0’
float                0.0
double               0.0
char Array[n]        ”
int Array[n]         {0,0…,0}
 ⑥判断一个字符是否为数字的两种方法(C/C++)

直接判断“

#include <stdio.h>
int main()
{   
    char c;
    c = getchar();//读取一个字符。
    if(c >='0' && c<='9')printf("是数字\n");
    else  if(c >='a' && c<='z' ||  c >='A' && c<='Z'))
        printf("是字母\n");
    else 
        printf("是特殊字符\n");
    return 0;
}

 库函数法

int main()
{
    char c;
    c = getchar();
    //来判断是否为数字,如果是数字那么会返回非0
    if(isdigit(c) != 0)
        printf("是数字\n") ;
    //来判断是否为字母,如果是字母那么返回非0
    else if(isalpha(c) != 0)
        printf("是字母\n"); 
    else
        printf("是特殊字符\n");
}

 十三届国赛心得:

字符串处理还是不精,老是忘记他们的作用,

还有常给我焊的板子ad不准调了两天最后发现是一个保险丝没焊。

lcd翻转显示不会

⑦串口接收初始化

//串口配置
	__HAL_UART_CLEAR_IDLEFLAG(&huart2);//防止一上电就进中断!!!!
	__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart2,Rx_buf,Buf_long);

 犯的错误:1、我用定时器2输出pwm时 占空比初始设置为了0,我用定时器三输入捕获总是读值CCR总是为0,最后发现我输出的pwm占空比为0就没有高低电平的改变,输入捕获时检测不到上升沿下降沿故读值总为0。

2、忽略了时序的问题,简单的几句话也封装函数造成了工程的冗余,蓝桥杯属于小工程比赛,我们可以直接将逻辑实现在while中。保证了时序的正确性,也避免了冗余,好修正错误。

3、eeprom的写入需要时间,故要加延时保证数据写入正确。而数据的读出一般不用加。且封装eeprom的读写函数时,当我们要指定地址读出一个字节时,最后应该给出I2CSendNotAck();

//eeprom 写入一个字节
void Write_onebyte(uint8_t ADDRESS,uint8_t byte)
{
	I2CStart();

	I2CSendByte(0xA0);
	I2CWaitAck();

	I2CSendByte(ADDRESS);
	I2CWaitAck();

	I2CSendByte(byte);
	I2CWaitAck();

	I2CStop();
}
void Read_onebyte(uint8_t ADDRESS,uint8_t *byte)
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();

	I2CSendByte(ADDRESS);
	I2CWaitAck();
	//I2CStop();  //可写可不写
	
	I2CStart();
	I2CSendByte(0xA1);
	I2CWaitAck();

	*byte = I2CReceiveByte();
	I2CSendNotAck();          //一定要发送的是不应答                  
	I2CStop();
	
}

4、单adc多通道采集时,要记得等待转换完成才能进行下一个通道的采集,否则会出现数据不准确情况。

5、别忘记输入捕获初始化函数如下:

	HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_2);

 我采用的主从触发模式,当采集到波形的一个周期的上升沿来临时CNT++,当下降沿来临时将CNT的值保存到CCR中,并且复位CNT的值,直到下一个周期的上升沿来临重复上次操作。获得捕获到的CCR的函数为

Temp= HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);

 6、当我们要判断接收的数据是什么时,可以采用如下方法:首先将数据强制转换为字符串,然后运用strcmp()比较字符串是否相等;

if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)==SET)
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除空闲中断标志位
		HAL_UART_DMAStop(&huart2);
		sprintf(Rx_temp,"%s",Rx_buf);  //将接收到的数字数据转为字符串(强制类型转换)
		if(strcmp(Rx_temp,"X")==0) //比较接收到的字符串是否为‘X’
		{
			
			char str[20]; //有符号八位字符(-128-127)
			sprintf(str,"Fre_para = %d\r\n",Fre_para);
			HAL_UART_Transmit(&huart2,(uint8_t *)str,strlen(str),20);
		
		}
	
//计算接收数据长度
//		Rceive_long = Buf_long-__HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
//		HAL_UART_Transmit(&huart2,Rx_buf,Rceive_long,20);
		//重新开启串口接收
		HAL_UART_Receive_DMA(&huart2,Rx_buf,Buf_long);
		
	}

后续还有总结,我会继续更的。如果有错误请指正呢
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值