搜索
bottom↓
12
返回列表 发新帖
楼主: tomzbj

准备给几个小弟办个速成班,哪位有经验么 @@

  [复制链接]

出0入115汤圆

发表于 2023-2-18 09:11:19 来自手机 | 显示全部楼层
现在主流是c make

出0入362汤圆

 楼主| 发表于 2023-2-18 10:56:42 | 显示全部楼层
三年模拟 发表于 2023-2-18 09:11
现在主流是c make
(引用自101楼)

这种所谓的主流不追也罢, Makefile到现在快50年了, 估计还能再战几十年,

qmake, scons, 个个号称要代替Makefile, 结果呢...

小弟们如果对什么新玩意儿感兴趣, 自己去学就是了, 我反正不鼓励也不反对, 个人爱好呗.

出0入115汤圆

发表于 2023-2-18 13:17:50 来自手机 | 显示全部楼层
本帖最后由 三年模拟 于 2023-2-18 13:21 编辑
tomzbj 发表于 2023-2-18 10:56
这种所谓的主流不追也罢, Makefile到现在快50年了, 估计还能再战几十年,

qmake, scons, 个个号称要代替 ...

(引用自102楼)


我喜欢用qmake配合qt creator的ide开发linux纯c,虽然没有宇宙第一ide vs studio舒服,但是也可以了,不用写make了,人的精力毕竟有限,写应用层还是专注代码方面,个人理解。

出0入362汤圆

 楼主| 发表于 2023-2-18 19:27:17 | 显示全部楼层
三年模拟 发表于 2023-2-18 13:17
我喜欢用qmake配合qt creator的ide开发linux纯c,虽然没有宇宙第一ide vs studio舒服,但是也可以了,不 ...
(引用自103楼)

Makefile基本也只需要从头写一次吧,然后每次在这个基础上稍微改改就行了……

出0入362汤圆

 楼主| 发表于 2023-2-24 10:44:51 | 显示全部楼层
2.24更新: 编译多个文件, 函数原型, 头文件, include, #ifndef避免重复包含
全局变量, 加static和extern的作用
写简单的Makefile,  依赖关系, -B和-j

出0入362汤圆

 楼主| 发表于 2023-3-21 15:14:36 | 显示全部楼层
更新:
3.3 数据结构初步, 时间和空间复杂度, 大O记号, 抽象数据类型

例题: 把一个字节按二进制逆序, 三种算法: 循环, 位运算处理, 查表
  1. unsigned char byte_reverse(unsigned char data)
  2. {
  3.     unsigned char output;
  4.     for(int i = 0; i < 8; i++) {
  5.         if(data & (1 << i))
  6.             output |= (1 << (7 - i));
  7.     }
  8.     return output;
  9. }

  10. unsigned char byte_reverse2(unsigned char data)
  11. {
  12.     data = (data >> 4) | (data << 4);
  13.     data = ((data & 0x33) << 2) | ((data & 0xcc) >> 2);
  14.     data = ((data & 0x55) << 1) | ((data & 0xaa) >> 1);
  15.     return data;
  16. }
复制代码


线性表的实现, 顺序表, 链表, 静态链表

3.10: 讲上次的习题, 栈和队列的概念, 递归, 回溯, 布置作业: 八皇后, 表达式求值

出0入0汤圆

发表于 2023-3-21 16:23:57 | 显示全部楼层
TINXPST 发表于 2022-3-18 17:52
楼主应该有现成的案例,我记得你之前不是做过一个用STM32F3做的LCR的一个小工程吗,就用这个项目让你的小弟 ...
(引用自37楼)

这倒是,在项目中闯关才是锻炼最快,最有效的途径

出0入362汤圆

 楼主| 发表于 2023-3-24 11:07:09 | 显示全部楼层
哈哈龅牙仔 发表于 2023-3-21 16:23
这倒是,在项目中闯关才是锻炼最快,最有效的途径
(引用自107楼)

从项目闯关也有缺点, 容易基本功不扎实, 以及对具体项目/公司的环境/工具链形成依赖.  开发环境/工具链这些东西不是真正的本事, 要是换了环境/工具链干不了活了那就废了.

比如我一直让他们用gcc+vim+Makefile干活, 今天才让他们换到eclipse里再调Makefile, 至于以后想用vscode什么的都随意了. 要是一开始就用eclipse或者vscode那恐怕以后没那么容易换环境了.

当然从企业的角度看更喜欢这样, 耗材么. 但是咱教学生不能把人往耗材的方向教.

感觉又有点象武侠小说里对正派和邪派武功的说法, 正派子弟从打坐运气站桩开始练, 进步缓慢, 邪派这边就讲究个入门迅速. 杨过靠速成的半招蛤蟆功就能秒杀大小武和鹿清笃等人.
但如果不是他确实资质优秀, 恐怕到后期就打不过差不多水平的正派子弟了.

如果是绝顶高手那就无所谓了, 怎么学都一样.

出0入362汤圆

 楼主| 发表于 2023-3-24 11:12:32 | 显示全部楼层
今天的内容: 现撸八皇后, 递归和非递归版本.
严格按面向对象的思路进行, 棋盘存储和所有放子、判断合法、输出操作作为一个类, 这样主函数这边就清爽多了.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入362汤圆

 楼主| 发表于 2023-3-31 22:55:06 | 显示全部楼层
今天带小弟们实现的内容:从零开始, 开发板LED闪灯

1. 把之前八皇后之类项目的main.c和Makefile复制出来, Makefile里SRC变量只留一个main.c, main.c里删空, 只留一个while(1) {},  然后make -B编译正常出main.exe.
2. Makefile里把gcc换成arm-none-eabi-gcc, 目标从main.exe换成main.elf, 编译正常出main.elf.
3. Makefile里加一个目标hex, 加上相应的依赖,效果是增加一条arm-none-eabi-objcopy -O ihex main.elf main.hex.
4. main.c开头增加#include "stm32f10x.h", main函数里增加

  1. RCC->APB2ENR |= RCC_APB2Periph_GPIOA;
  2. GPIOA->CRL &= ~(0xf << (6 * 4));
  3. GPIOx->CRL |= (((GPIO_Mode_AF_PP & 0xf) | GPIO_Speed_50MHz) << (6 * 4));
复制代码

while(1)里再放个
  1. GPIOA->ODR ^= GPIO_Pin_6;
  2. for(volatile int i = 0; i < 1000000UL; i++) {}
复制代码


编译完下载到开发板, 不能运行。
5. 因为没有指定目标地址, 找个lds文件, 然后Makefile里链接命令加上-T xxx.lds, 再编译, 提示找不到Reset_Handler, 这是因为没有启动文件.
6. 再找个启动文件, Makefile里加上ASRC = xxx.s,  AS = gcc, OBJL加上$(ASRC:.s=.o), 依赖关系再加上
  1. %.o: %.s
  2.         $(AS) -c $(ASFLAGS) $< -o $@
复制代码

7. 编译, 提示找不到SystemInit函数, 再在main.c里加上空的SystemInit.
8. 编译成功, 下载到开发板, 还是不能运行, 直接进HardFault. 原因是没有指定指令集和MCU内核.
9. Makefile里CFLAGS变量加上-g -gdwarf-2 -mthumb -mcpu=cortex-m3, 再编译, 下载到开发板, 灯闪了.
10. for循环里i < 1000000UL改成100000UL, 去掉一个零, 再编译下载, 闪灯果然快了很多.

小弟们表示这个Makefile比网上各种例子里的简单多了.
再就是在目标里加了一行size, 编译完显示.text .data .bss字节数.

下次课预备先加上生成map和lst文件用于调试, 然后是命令行实现stlink烧写, 初始化时钟PLL, GPIO各种工作模式, 争取再讲点串口.

出0入0汤圆

发表于 2023-4-1 00:38:34 | 显示全部楼层
tomzbj 发表于 2022-3-17 16:13
简单列个大纲,到时候边讲边完善吧

一.模拟电路
(引用自7楼)

小弟们学会MultiSIM了么

出0入362汤圆

 楼主| 发表于 2023-4-1 10:52:42 | 显示全部楼层
Franso 发表于 2023-4-1 00:38
小弟们学会MultiSIM了么
(引用自111楼)

早就会了啊, 这还用教多久?

出0入362汤圆

 楼主| 发表于 2023-4-8 22:15:25 | 显示全部楼层
本帖最后由 tomzbj 于 2023-4-8 22:29 编辑

4.7课程更新:

0. 在上次的基础上, Makefile前面加一行:
  1. STLINK := "C:/Program Files (x86)/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility/ST-LINK_CLI.exe"
复制代码


后面加两行:
  1. flash:
  2.         $(STLINK) -c SWD freq=4000 -P $(TARGET).hex -V -Rst
  3. reset:
  4.         $(STLINK) -c SWD -Rs
复制代码

于是在命令行执行make flash和make reset就可以实现下载和复位了.
1. main.c, 把闪灯的部分单独拿出来做成一个函数gpio_toggle, 在main函数里调用, 再在这个函数里加个while(1); 于是程序运行到这里就卡死了.
2. 用stlink连接,  MCU Core, 单步运行, PC寄存器的值一直不动, 说明死循环了.
3. 但是怎么从PC的值知道卡在哪里? 首先在Makefile里加一行:
  1. LDFLAGS += -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch
复制代码

4. 再编译运行, 多了一个main.map, 在里面查找PC寄存器对应的地址, 于是可以知道是卡在哪个函数里了.
5. 在gpio_toggle函数里加个void (*func)(void), 让它指向NULL, 然后直接调用这个函数指针, 于是又卡死了.
6. 再用stlink连接, 检查PC寄存器, 再对照main.map, 这次卡在Default_Handler了. 这是因为没有明确给出HardFault_Handler, 而启动文件里有个弱符号HardFault_Handler是Default_Handler的别名.
7. main.c里再加一段:
  1. void HardFault_Handler(void)
  2. {
  3.         while(1);
  4. }
复制代码

8. 再编译运行, stlink检查PC寄存器, 这次确定是卡在HardFault_Handler了. 但是怎么知道是从哪掉进HardFault的?
9. 查R13寄存器, 把里面的值复制到addr里, 读取几十字节, 再看第6或第7个32位值, 这是掉进HardFault之前的地址, 再对照main.map检查, 这次知道是在gpio_toggle函数里出错了.
10. 查map文件还是嫌太麻烦怎么办? 再在Makefile里给CFLAGS加一行 -Wa,-ahlms=$(<:.c=.lst), 编译运行, 这次又多了main.lst文件.
11. 卡住了, 用stlink知道了地址, 命令行执行
  1. arm-none-eabi-addr2line 地址 -e main.elf
复制代码
, 这次直接给了出错的文件名和行号.
12. 小弟们大概知道调试流程了. 最后在之前空白的SystemInit函数里加上配置时钟的内容:
  1.   RCC_DeInit();
  2.     FLASH_SetLatency(FLASH_Latency_0);
  3.     RCC_HSEConfig(RCC_HSE_ON);
  4.     int ret = RCC_WaitForHSEStartUp();
  5.     if(ret == 0x01) {
  6.         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
  7.         FLASH_SetLatency(FLASH_Latency_2);
  8.    
  9.         RCC_HCLKConfig(RCC_SYSCLK_Div1);
  10.         RCC_PCLK2Config(RCC_HCLK_Div1);
  11.         RCC_PCLK1Config(RCC_HCLK_Div2);
  12.         RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);
  13.         RCC_PLLCmd(ENABLE);
  14.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
  15.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  16.         while(RCC_GetSYSCLKSource() != 0x08);
  17.     }
复制代码

13. 上面这个SystemInit相比system_stm32f10x.c里的版本相对简单明了一些.  给他们讲清楚, 每一行起什么作用, 为什么网上各种例子是RCC_PLLSource_HSE_Div1而我们这个是Div2, 因为各种STM32开发板一般用8M晶振而我们这个是16M的, 因此需要预先把HSE时钟二分频再进PLL.
14. 编译运行, 这次LED闪烁频率果然比之前快多了.
15. 指导他们实现简单的延时函数, 顺便说明, 初始化阶段可以使用ms级延时, 进入主循环之后只允许使用us级延时. 调度器之类以后再讲. 参数加volatile则是为了避免被编译器给优化掉.
  1. void _delay_us(volatile int nus)
  2. {
  3.     nus *= 7;
  4.     while(nus > 0) {
  5.         nus--;
  6.     }
  7. }

  8. void _delay_ms(volatile int nms)
  9. {
  10.     while(nms > 0) {
  11.         _delay_us(1000);
  12.         nms--;
  13.     }
  14. }
复制代码

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 06:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表