假期第1周-学习备忘录

日期 星期 时间记录 学习内容 日合计
1.18 1 0
1.19 2 0
1.20 3 14:30-17:00
19:00-21:00
CAN总线 TJA1050控制器试验 4.5
1.21 4 13:30-17:00
19:00-22:00
CAN总线 TJA1050控制器试验 6.5
1.22 5 13:30-17:00
19:00-22:00
Arduino CAN总线试验 6.5
1.23 6 14:30-17:00
19:00-21:00
Arduino CAN总线试验 4.5
1.24 7
周合计时间
周平均时间

1 尝试办法1:不进行引脚复用,通过拉高输入和推挽输出的方式使用CAN总线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
if(CANChannel == 0)
{
RCC->APB1ENR1 |= RCC_APB1ENR1_CAN1EN;
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
// GPIOA->MODER &= ~(GPIO_MODER_MODE11|GPIO_MODER_MODE12);
// GPIOA->MODER |= (GPIO_MODER_MODE11_1|GPIO_MODER_MODE12_1);
// GPIOA->AFR[1] &= ~(GPIO_AFRH_AFSEL11|GPIO_AFRH_AFSEL12);
// GPIOA->AFR[1] |= (GPIO_AFRH_AFSEL11_0|GPIO_AFRH_AFSEL11_3)| (GPIO_AFRH_AFSEL12_0|GPIO_AFRH_AFSEL12_3);
GPIOA->OTYPER &= ~GPIO_OTYPER_OT12;
GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED12;
GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED12_1;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD11;
GPIOA->PUPDR |= GPIO_PUPDR_PUPD11_0;
}
else if(CANChannel == 1)
{
RCC->APB1ENR1 |= RCC_APB1ENR1_CAN1EN;
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;
GPIOB->MODER &= ~(GPIO_MODER_MODE8|GPIO_MODER_MODE9);
GPIOB->MODER |= (GPIO_MODER_MODE8_1|GPIO_MODER_MODE9_1);
GPIOB->AFR[1] &= ~(GPIO_AFRH_AFSEL8|GPIO_AFRH_AFSEL9);
GPIOB->AFR[1] |= ((GPIO_AFRH_AFSEL8_0|GPIO_AFRH_AFSEL8_3)|
(GPIO_AFRH_AFSEL9_0|GPIO_AFRH_AFSEL9_3));
}
else
{
RCC->APB1ENR1 |= RCC_APB1ENR1_CAN1EN;
RCC->AHB2ENR |= RCC_AHB2ENR_GPIODEN;
GPIOD->MODER &= ~(GPIO_MODER_MODE0|GPIO_MODER_MODE1);
GPIOD->MODER |= (GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_1);
GPIOD->AFR[0] &= ~(GPIO_AFRL_AFSEL0|GPIO_AFRL_AFSEL1);
GPIOD->AFR[0] |= ((GPIO_AFRL_AFSEL0_0 | GPIO_AFRL_AFSEL0_3)|
(GPIO_AFRL_AFSEL1_0 | GPIO_AFRL_AFSEL1_3));
}

2 尝试办法2:使用CAN控制器:将STM32板子中的CAN_RX,CAN_TX,VCC,GND接入到CAN控制器中引出CAN_H和CAN_L引脚并接入到CAN_H线和CAN_L线上。

3 尝试办法3:使用MCP2515与Arduino试验,类比到STM32中。

4 目前状况

CAN模块初始化为环回模式时,可以进行正确的发送一帧数据和接收一帧数据,正常模式无法出现现象,引脚功能复用为CAN无法接收信息,不确定是引脚组未配置成功还是硬件接线未成功。

第16周-学习备忘录

日期 星期 时间记录 学习内容 日合计
12.21 1 9:00-11.30
13:00-17:30
19:00-22:30
软件著作权使用软件界面及功能修改 10.5
12.22 2 9:00-11.30
13:00-17:30
19:00-22:30
软件著作权使用软件界面及功能修改 10.5
12.23 3 9:00-11.30
13:00-17:30
19:00-22:30
软件著作权使用软件界面及功能修改 10.5
12.24 4 9:00-11.30
13:00-17:30
软件著作权撰写 7
12.25 5 9:00-11.30
13:00-17:30
软件著作权撰写 7
12.26 6
12.27 7
周合计时间
周平均时间

第15周-学习备忘录

日期 星期 时间记录 学习内容 日合计
12.14 1 9:00-11.30
13:00-17:30
19:00-22:30
组会
软件著作权撰写
10.5
12.15 2 9:00-11.30
13:00-17:30
19:00-22:30
软件著作权撰写 10.5
12.16 3 9:00-11.30
13:00-17:30
19:00-22:30
软件著作权撰写 10.5
12.17 4 9:00-11.30
13:00-17:30
软件著作权撰写 7
12.18 5 9:00-11.30
13:00-17:30
软件著作权撰写 7
12.19 6
12.20 7
周合计时间
周平均时间

20201215会议要点总结

会议主题:软件著作权

要求

1.技术指标要完善,有论文的各人弄一个,没论文的各人弄两个。

2.软著所用需要真做,找两个内容完全不一样的。

3.12页以上,参考张蓉的文章写作格式,需要嵌入式端代码和PC端代码

4.元月5号前完成,需要简介500字,软硬件环境,主要功能与技术特点1000字,技术参数说明书12页

第14周-学习备忘录

日期 星期 时间记录 学习内容 日合计
12.7 1 9:00-11.30
13:00-17:30
19:00-22:30
组会
复现烧录卡死问题
解决问题
10.5
12.8 2 9:00-11.30
13:00-17:30
19:00-22:30
整合IDE&BIOS&动态命令 10.5
12.9 3 9:00-11.30
13:00-17:30
18:30-20:00
六级复习 10.5
12.10 4 9:00-11.30
13:00-17:30
六级复习 7
12.11 5 9:00-11.30
13:00-17:30
18:30-20:00
六级复习 7
12.12 6
12.13 7
周合计时间
周平均时间

20201210会议要点总结

1.针对优化等级出现的问题提出要求—指令延时不进行优化

2.为什么SRAM区需要两个

3.论文要求:不要挂老师名字、写论文要有导语、做事情一定要认真、提高认真度0.1%。

位带区与别名区介绍

位带区与别名区组合使用形成了位带操作,首先对为什么要引进位带操作进行简介。

1.位带操作的意义

​ 在MCU编程中,通常情况下,对RAM1及外设寄存器的操作,只能对整个字执行“读-改-写”操作,而只对字中某位的操作则需要位带操作的支持。

2.位带操作概述

​ 位带操作实质是一种内存映射关系,系统将“位带区”的存储单元按“位”映射到对应的“别名区”的32位字上,“别名区”中的一个32位地址,对应“位带区”一个地址中的一个位。按“字”访问“别名区”的存储单元时,就相当于访问“位带区”对应“位”,即通过对“别名区”地址的访问等同于对真实地址的某个位的访问。

3.位带操作应用案例解析

以SRAM1中目标地址为0x2000_0300,修改其第二位为“0”为例:一般情况下,修改内存中的一位不影响其他位。

​ ①不使用位带操作方法

​ 需要对待修改的字执行“读-改-写”操作,即读内存赋给临时变量,然后对临时变量进行修改,最后将临时变量结果写回内存。具体方法如下:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
//读一个字:读取0x20000300~0x20000303中内容到临时变量temp中
temp = (*(volatile unsigned long int*)(unsigned long int)0x20000300)

//改一个位:将temp中的第2位清0(从左向右为31--0)
temp = temp & 0xFFFFFFFB

//写一个字:将temp写回目标地址
(*(volatile unsigned long int*)(unsigned long int)0x20000300) = temp;
}

​ 在AHL-GEC-IDE中对上述代码反汇编进行对比,可以发现使用位带操作比原有“读-改-写”方法的代码空间要小,执行效率更高。通过“别名区”的写操作就可以实现对SRAM1中位的操作,将位操作的“读-改-写”过程就变为了只有“写”的操作,提高了程序的运行效率。

一般情况下,“位带区”中修改一位的机器码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
__main:
//"位带区"读一个字
temp = (*(volatile unsigned long int*)(unsigned long int)0x20000300);
800e5d4: 4b0a ldr r3,[pc,#40]
800e5d6: 681b ldr r3,[r3,#0]
800e5d8: 607b str r3,[r7,#4]

//改一个位
temp = temp & 0xFFFFFFFB;
800e5e2: 4a07
800e5e4: 687b
800e5e6: 6013

//位带区写一个字
(*(volatile unsigned long int*)(unsigned long int)0x20000300) = temp;
800e5e2: 4a07
800e5e4: 687b
800e5e6: 6013

​ ②使用位带操作方法

​ 如果使用位带操作将“位带区”地址为0x2000_0300的内存单元第2位变成“0”。仅需一步写操作就可以实现。

1
2
3
4
5
6
int main()
{
(*(volatile unsigned long int*)(unsigned long int)0x22006008) = 0;
//"别名区"的地址0x20006008通过公式 0x22000000 + ((0x20000300 - 0x20000000) * 32) + (2 * 4)
//3*32 = 96 96/16 = 6 --> 0x20000300对应 0x22006000,再加上2位偏移地址即成为0x22006008
}
地址 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0x20000300 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1
0x20000301 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1

​ Tips:每个地址包含了8个bit位,在无符号整数中,0x20000300地址中存放的数是从0到255,在有符号整数中,0x20000300地址中存放的数是从-128到127,也就是一个byte位,short占据两个地址(byte),所以在无符号整数中可以表示0-65535,有符号整数中可以表示-32768到32767,int占据四个地址(byte),所以在无符号整数中可以表示0-4294967296,在有符号整数中可以表示-2147483648-2147483647。

​ 在位带操作下,0x20000300中被映射到一个32个地址,这个地址下的每一个比特位都对应别名区的4个地址,0x20000300的bit0被映射成了0x20006000,bit1被映射成了0x20006004,bit2被映射成了0x20006008,bit3被映射成了0x2000600C,bit4被映射成了0x20006010,bit5被映射成了0x20006014,bit6被映射成了0x20006018,bit7被映射成了0x2000601C,0x20000301的bit0被映射成了0x20000620,以此类推。。。。。。

​ 从上面的特性可以知道,位带区的一个字节会被映射称32个地址,即1位映射为4个地址(32位),那么一个48K的”位带区“就需要一个32×48K的”别名区“进行位带操作,一个1MB的”位带区“就需要一个32×1MB的”别名区“进行位带操作。

4.

第2个B类问题-灌写程序后卡死

问题出现的现象

​ 1.灌写程序后卡死问题解决后,出现User程序灌写后不执行,按复位键程序之间跳回到BIOS。

​ 2.在未使用投屏时,程序大概率可以灌写成功,使用投屏后,程序大概率灌写失败。

​ 3.第一扇区在烧写后机器码消失,其他扇区存在机器码。

​ 4.在O0编译下能够烧写成功,在O1编译下大概率烧写失败。

问题出现的原因

​ 在O1优化等级下,函数循环被优化,循环被加快(具体优化可见嵌入式系统—8-编译优化等级详解),导致在O1优化下延时过短,进入跳转程序后,由于芯片电压不稳定,程序第一扇区被擦写后无法重新写入,导致第一扇区机器码消失。

问题解决的过程

​ 1.由于未使用投屏程序可以正常灌写,而使用投屏无法正常灌写,而且无法在其他机器上复现问题,认定是PC机的问题。后在未投屏情况下已经其他电脑中也发现类似情况,排除是投屏导致的问题。

​ 2.多次测试后,发现灌写程序后第一扇区机器码消失,认定Flash构件有问题,在Flash写入前后加了延时和其他保护措施以及在上位机添加延时,发现未能解决问题。

​ 3.经王老师使用反馈,O0编译下程序灌写不会出错,O1编译下程序出现错误,将问题在本机复现。

​ 4.由于第一扇区机器码被擦除,对每一帧进行了断点调试,发现写入第二帧后第一帧机器码并未消失,并且写完所有帧后,前面机器码均未消失,认定写入过程并未出现异常,并且手动按下复位键程序可以正常运行,而通过上位机复位第一帧依旧被擦除,定位至底层复位时发生问题,结合对编译优化等级的理解定位至循环问题,加大循环时间或不优化即可解决问题。

问题解决的办法

​ 1.加大延时时间,由原来的20000改成100000。

​ 2.对循环使用的变量采取不优化策略,将uint32_t改为vuint32_t。