stm32学习 c语言笔记
STM32中C语言知识点:初学者必看
这个例子中只有几行代码,我们很快就可以找到程序蹦的原因就是变 量 c 的值为 0。但是,如果代码量很大,我们还能这么快的找到问题 点吗? 这时候,assert()就派上用场了,以上代码中,我们可以在 a = b / c;这 句代码之前加上 assert(c);这句代码用来判断变量 c 的有效性。此时, 再编译运行,得到的结果为:
// ...... #endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
#if 的使用一般使用格式如下 #if 整型常量表达式 1
程序段 1 #elif 整型常量表达式 2
程序段 2 #else
程序段 3 #endif
执行起来就是,如果整形常量表达式为真,则执行程序段 1,以此类 推,最后#endif 是#if 的结束标志。 (2)#ifdef、#ifndef
我们使用#pragma pack 指令来指定对齐的字节数。例子: ①指定按 1 字节对齐
运行结果为:
②指定 2 字节对齐
运行结果为:
可见,指定的对齐的字节数不一样,得到的结果也不一样。指定对齐 有什么用呢,大概就是可以避免了移植过程中编译器的差异带来的代 码隐患吧。比如两个编译器的默认对齐方式不一样,那可能会带来一 些 bug。 (2)#pragma message 该指令用于在预处理过程中输出一些有用的提示信息,如:
可见,程序蹦的同时还会在标准错误流中打印一条错误信息: Assertion failed:c, file hello.c, line 12 这条信息包含了一些对我们查找 bug 很有帮助的信息:问题出在变 量 c,在 hello.c 文件的第 12 行。这么一来,我们就可以迅速的定位 到问题点了。 这时候细心的朋友会发现,上边我们对 assert()的介绍中,有这么一 句说明: 如果表达式的值为假,assert()宏就会调用_assert 函数在标准错误流 中打印一条错误信息,并调用 abort()(abort()函数的原型在 stdlib.h 头文件中)函数终止程序。 所以,针对我们这个例子,我们的 assert()宏我们也可以用以下代码 来代替: if (0 == c) { puts("c 的值不能为 0,请重新输入!"); abort(); }
stm32自学笔记共20页
•
LED0=1;
•
LED1=0;
•
delay_ms(300);
•
}
•}
第二章 跑马灯实验
• Led.c函数
• void LED_Init(void)
•{
•
RCC->APB2ENR|=1<<2; //使能PORTA时钟
•
GPIOA->CRH|=0XFFFFFFFF3;//PA8 推挽输出
•
GPIOA->ODR|=1<<8; //PA8 输出高
• JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD,在原理图上可以看 到PA13和PA15为键盘和JTAG与SWD所共用,而这两种方针接口,他们 和普通的IO口公用,当想使用普通IO口时,必须先把他们关闭。在这 个函数里面设置参数,如果为二进制数00,则代表全部使能,如果是 二进制数01,则是能SWD,如果是10,则表示全部关闭。JTAG是一种 国际标准测试协议,主要用于芯片内部的测试。
• }要想实现一个点亮led小灯的功能,最少只需对3个寄存器进行设 置,第一步是设置外设时钟使能先把PORTA时钟使能,接下来把IO
口设置为输出,在接下来设置输出为高电平还是低电平,这里使用 推挽输出(3.3v),推挽输出主要是增强驱动能力,为外部提供大电 流。
第二章 跑马灯实验
• #ifndef __LED_H • #define __LED_H • #include "sys.h" • #define LED0 PAout(8)// PA8 • #define LED1 PDout(2)// PD2 • void LED_Init(void);//初始化
STM32学习笔记
串口:一. USART_ITConfig(USART1, USART_IT_TXE, ENABLE):只要发送寄存器为空,就会一直有中断,因此,要是不发送数据时,把发送中断关闭,只在开始发送时,才打开。
二.以下是字符发送的配置过程,注意第6点,在设置USART_CR1中的TE位时,会发送一个空闲帧作为第一次数据发送,所以即便你执行了USART_ClearFlag(USART1, USART_FLAG_TC); (这个函数肯定在空闲帧数据发送完成前执行),所以当空闲帧发送完后,就进入发送完成中断。
配置步骤:1. 通过在USART_CR1寄存器上置位UE位来激活USART2. 编程USART_CR1的M位来定义字长。
3. 在USART_CR2中编程停止位的位数。
4. 如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMA T)。
按多缓冲器通信中的描述配置DMA寄存器。
5. 利用USART_BRR寄存器选择要求的波特率。
6. 设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。
7. 把要发送的数据写进USART_DR寄存器(此动作清除TXE位)。
在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。
8. 在USART_DR寄存器中写入最后一个数据字后,要等待TC=1,它表示最后一个数据帧的传输结束。
当需要关闭USART或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。
解决的办法:方法一在执行USART_ITConfig(USART1, USART_IT_TC, ENABLE); 之前,先延时一段时间,基本上比一个字符发送的时间长一点就可以了,然后再执行USART_ClearFlag(USART1, USART_FLAG_TC);方法二:在执行USART_ITConfig(USART1, USART_IT_TC, ENABLE); 之前,USART_ClearFlag(USART1, USART_FLAG_TC);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){; //等待空闲帧发送完成后再清零发送标志}USART_ClearFlag(USART1,USART_FLAG_TC);三.TXE:发送缓冲器空闲标志RXNE:接收缓冲区非空IAP:一.问:这几天在折腾STM32的IAP,参考了两个例程,一个AN2557,然后一个就是标准外设库内的flash例程总结IAP:1.Flash解锁 FLASH_Unlock();2.清除Flash所有的未完成的标志位 FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);3.根据文件大小擦除Flashfor(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE ); EraseCounter++){FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter));}4.编程Flashwhile((Address < EndAddr) && (FLASHStatus == FLASH_COMPLETE)){FLASHStatus = FLASH_ProgramWord(Address, Data);Address = Address + 4;}5.检验编入数据的正确性while((Address < EndAddr) && (MemoryProgramStatus != FAILED)){if((*(__IO uint32_t*) Address) != Data){MemoryProgramStatus = FAILED;}Address += 4;}在以上几步中,如果上面没有问题的话,提出下面几个疑问1.假如我的应用程序的地址应该从0x8003000开始,那么我把后面的页全部擦除是否可以? 虽然我的程序可能只占到0x8003000-0x8005000 那么这之后的页是否也可以一并擦除?2.在编程的时候有个很小的问题,因我的数据都是以字节(byte)的形式储存的,在写的时候因为只能以半字(16位)或一个字(32位)的方式编程,那么如果我的bin文件的最后一个字节并不够两个字节,怎么办?举例:我的bin文件的大小是501个字节(8位),我的写入方法是这样的:data[501] = {X,X,X...}//应用程序bin文件内容temp = data[0];temp = temp << 8;temp |= data[1];temp = temp << 8;temp |= data[2];teme = temp << 8;teme |= data[3];//待写入得数据FLASHStatus = FLASH_ProgramWord(Address, temp);//写入flash如果像这样的话,那么不能被4整除的那一个字节怎么办?3.IAP程序中有一处一直很迷惑,不能理解/* Test if user code is programmed starting from address "ApplicationAddress" */if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000){ /* Jump to user application */JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();}程序的整体是要跳出IAP引导区跳到应用程序区.那么这句判断的依据是什么?if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)倘若我今天的程序是重0x8003000处开始,那么明天我升级一个程序,他的开始是0x80080000呢?这里需要改吗?0x2FFE0000 0x20000000 这两个数我在AN2557的例子代码里反复寻找,并没有哪里出现,那么又是怎么跟用户的应用程序关联的呢?还有如果将上面的例子直接这样更改,是否可以达到跳转到应用程序区的目的呢?/* Jump to user application */JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); //这里为何要+4 ?+了4不就跳过出应用程序的入口了吗?Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();4.关于Flash的写保护问题,在3.0标准外设库中Flash还有另外一个例子,就是关于保护的无疑flash的保护是对程序的一个安全保障,但目前我买的新片子(未进行过任何保护方面的操作)中,是否不需要考虑这些问题,直接擦除,然后编程即可?5.有什么理由要“今天的程序是重0x8003000处开始,明天又升级一个程序,他的开始是呢”?第1没有必要,第2是自寻烦恼。
STM32学习笔记
STM32学习一、初识库(略)二、(略)三、(略)四、(略)五、(略)六、系统定时器1、注意外部函数的声明;2、与六相同,也使用了中断;3、Volatile是不让编译优化的意思;4、Extern即定义外部函数,static是静态变量的意思。
七、串口通信1、当使用printf时,记得要在“bsp_usart1.h”文件中把“stdio.h”包含进来2、NVIC是中断优先级配置函数3、注意使用微库右图中的Use Micro LIB要打勾4、八、DMA1、DMA含义:data memory access,直接内存访问,此时不经过CPU2、这种方式节省CPU资源,好像可以同时做两件事(ADC、SPI、I2C等),不同的外设通道不同,可参看数据手册,串口1是通道4九、ADC1、ADC为12位,时钟为14MHz,最小采样时间为1微秒2、要提高采集频率,可采用多通道交叉采样。
十、FSMC液晶显示1、FSMC含义:灵活的静态存储器控制器2、注意配置IO引脚的第二功能时应注意配置成“AF-pp”即复用推挽模式;3、注意片选BANK1-44、野火自带的屏的高度840,宽320十一、I2C总线1、I2C一般都是开漏输出2、一般向I2C写数据时,如不加限制,是从头开始,写到本页结束如果再写又回到本页开头,会覆盖原来内容,因此,为避免这种情况,加地址。
十二、SPI总线1、SPI总线的读写速度(特别是读速度)要比对SD卡的快,而且成本低;2、SPI总线模块可存汉字字库、图片等,一些掉电保护信息也可存于此;3、在“bsp_spi_flash.c”中,语句“RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOD, ENABLE);”中的D端口时钟不需要开,即“RCC_APB2Periph_GPIOD”是不必要的,可以删去;4、“sizeof()”是C语言的保留字,其用法在此有描述。
STM32入门C语言详解
阅读flas h:芯片内部存储器flas h操作函数我的理解——对芯片内部f lash进行操作的函数,包括读取,状态,擦除,写入等等,可以允许程序去操作fl ash上的数据。
基础应用1,FLASH时序延迟几个周期,等待总线同步操作。
推荐按照单片机系统运行频率,0—24MHz时,取Laten cy=0;24—48MHz时,取Laten cy=1;48~72MHz时,取Laten cy=2。
所有程序中必须的用法:FLASH_SetLa tency(FLASH_Laten cy_2);位置:RCC初始化子函数里面,时钟起振之后。
基础应用2,开启FLAS H预读缓冲功能,加速FLAS H的读取。
所有程序中必须的用法:FLASH_Prefe tchBu fferC md(FLASH_Prefe tchBu ffer_Enabl e);位置:RCC初始化子函数里面,时钟起振之后。
3、阅读lib:调试所有外设初始化的函数。
我的理解——不理解,也不需要理解。
只要知道所有外设在调试的时候,EWRAM需要从这个函数里面获得调试所需信息的地址或者指针之类的信息。
基础应用1,只有一个函数debug。
所有程序中必须的。
用法: #ifdefDEBUGdebug();#endif位置:main函数开头,声明变量之后。
4、阅读nvic:系统中断管理。
我的理解——管理系统内部的中断,负责打开和关闭中断。
基础应用1,中断的初始化函数,包括设置中断向量表位置,和开启所需的中断两部分。
所有程序中必须的。
用法: void NVIC_C onfig urati on(void){NVIC_I nitTy peDef NVIC_I nitSt ructu re; //中断管理恢复默认参数#ifdefVECT_T AB_RA M //如果C/C++ Compil er\Prepro cesso r\Define d symbol s中的定义了VECT_TAB_RAM(见程序库更改内容的表格)NVIC_S etVec torTa ble(NVIC_V ectTa b_RAM, 0x0); //则在RAM调试#else //如果没有定义VECT_TAB_R AMNVIC_S etVec torTa ble(NVIC_V ectTa b_FLA SH, 0x0);//则在Flas h里调试#endif//结束判断语句//以下为中断的开启过程,不是所有程序必须的。
stm32学习笔记(狼牙整理)
系统时钟 SYSCLK 最大频率为 72MHz,它是供 STM32 中绝大部分部件工作的时钟源。 系统时钟可由 PLL、HSI 或者 HSE 提供输出,并且它通过 AHB 分频器分频后送给各模 块使用,AHB 分频器可选择 1、2、4、8、16、64、128、256、512 分频。其中 AH B 分频器输出的时钟送给 5 大模块使用:①、送给 AHB 总线、内核、内存和 DMA 使用 的 HCLK 时钟。 ②、分频后送给 STM32 芯片的系统定时器时钟(Systick=Sysclk/8=9Mhz) ③、直接送给 Cortex 的自由运行时钟(free running clock)FCLK。【ARMJISHU 注:FCL K 为处理器的自由振荡的处理器时钟,用来采样中断和为调试模块计时。在处理器休眠时, 通过 FCLK 保证可以采样到中断和跟踪休眠事件。 Cortex-M3 内核的“自由运行时钟(fre e running clock)”FCLK。“自由”表现在它不来自系统时钟 HCLK,因此在系统时钟停 止时 FCLK 也继续运行。FCLK 和 HCLK 互相同步。FCLK 是一个自由振荡的 HCLK。FCL K 和 HCLK 应该互相平衡,保证进入 Cortex-M3 时的延迟相同。】④、送给 APB1 分频 器。APB1 分频器可选择 1、2、4、8、16 分频,其输出一路供 APB1 外设使用(PCLK1, 最大频率 36MHz),另一路送给定时器(Timer)2、3、4 倍频器使用。该倍频器可选择 1 或 者 2 倍频,时钟输出供定时器 2、3、4 使用。 ⑤、送给 APB2 分频器。APB2 分频器可选择 1、2、4、8、16 分频, 其输出一路供 APB 2 外设使用(PCLK2,最大频率 72MHz),另一路送给定时器(Timer)1 倍频器使用。该倍频
stm32--C语言
1.12,最易变的关键字----volatilevolatile是易变的、不稳定的意思。
很多人根本就没见过这个关键字,不知道它的存在。
也有很多程序员知道它的存在,但从来没用过它。
我对它有种“杨家有女初长成,养在深闺人未识”的感觉。
volatile关键字和const一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。
遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
先看看下面的例子:int i=10;int j = i;//(1)语句int k = i;//(2)语句这时候编译器对代码进行优化,因为在(1)、(2)两条语句中,i 没有被用作左值。
这时候编译器认为i 的值没有发生改变,所以在(1)语句时从内存中取出i的值赋给j 之后,这个值并没有被丢掉,而是在(2)语句时继续用这个值给k赋值。
编译器不会生成出汇编代码重新从内存里取i 的值,这样提高了效率。
但要注意:(1)、(2)语句之间i没有被用作左值才行。
再看另一个例子:volatile int i=10;int j = i;//(3)语句int k = i;//(4)语句volatile关键字告诉编译器i是随时可能发生变化的,每次使用它的时候必须从内存中取出i 的值,因而编译器生成的汇编代码会重新从i 的地址处读取数据放在k 中。
这样看来,如果i 是一个寄存器变量或者表示一个端口数据或者是多个线程的共享数据,就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
但是注意:在VC++6.0中,一般Debug模式没有进行代码优化,所以这个关键字的作用有可能看不出来。
你可以同时生成Debug版和Release版的程序做个测试。
2、定义const只读变量,具有不可变性。
const int *p; // p 可变,p指向的对象不可变int const *p; // p可变,p指向的对象不可变int*constp; //p不可变,p指向的对象可变const int *const p; //指针p和p指向的对象都不可变在平时的授课中发现学生很难记住这几种情况。
STM32学习笔记小结
STM32学习笔记目录STM32学习笔记 (1)一、入门 (2)目标->实战项目 (2)STM32学习方法 (3)ARM简介 (4)二、外设功能模块 (5)GPIO原理与工作模式 (5)串行通信 (6)硬件下载与调试 (6)Cortex-M3复用功能(AF)和重映射功能 (6)Systick的使用 (7)通用定时器 (7)SPI与数码管 (7)I2C通信 (8)NVIC中断 (8)PWM基础 (9)RCC内部结构与原理 (9)ADC模数转换 (10)内部温度传感器 (10)窗口看门狗 (10)USB应用 (11)三、问题 (11)在线调试 (12)一、入门STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M内核,主要包括STM32F101“基本型”系列、STM32F103“增强型”系列、STM32F105、STM32F107“互联型”系列。
STM32微控制器满足嵌入式开发低功耗和高性能的要求,并且拥有简单易上手的固件函数库,避免了传统ARM单片机开发操作寄存器的模式,所以十分受欢迎,应用广泛。
作者只学过一些51单片机的基础,就直接上手STM32,边学边用。
该篇笔记也是随意的记录一下,要想系统的学习一下,个人认为资料手册(data sheet)、参考手册(Reference Manual)和用户手册(固件函数库)三个文档再有开发板实际操作,完全足够。
熟练掌握以上内容,触类旁通,成为STM32开发的高手指日可待。
目标->实战项目STM32学习方法开发环境(MDK/IAR)→寄存器or固件库→软件仿真&开发板硬件→学习难度建立不受库版本限制的工程项目:1.准备好文件(Startup Code、Lib、User)2.建立工程不添加Startup Code3.工程管理添加需要的库文件、自定义文件4.编译链接ARM简介ARM7衍生出全新的Cortex架构,三管齐下:Cortex-A:高性能应用处理器。
STM32中C语言知识点初学者必看
STM32中C语言知识点初学者必看1. 数据类型:在C语言中,常用的数据类型包括整型(如int、long)、浮点型(如float、double)、字符型(如char),以及指针类型等。
2.变量和常量:变量是用来存储数据的,而常量是固定的数值,不可修改。
3. 运算符:C语言提供了一系列的运算符,包括算术运算符(如+、-、*、/),关系运算符(如<、>、==、!=),逻辑运算符(如&&,!),位运算符(如&,^),赋值运算符(如=、+=、-=),以及其他一些特殊的运算符(如sizeof、?:)等。
4. 控制语句:C语言提供了若干种控制语句,包括条件语句(如if、switch),循环语句(如for、while、do-while),以及跳转语句(如break、continue、goto)等。
5.数组:数组是一种用于存储相同类型数据的结构,可以通过下标来访问数组中的元素。
6.字符串:字符串是由字符组成的数组,在C语言中,字符串以'\0'结尾。
7.函数:函数是一段具有特定功能的代码块,可以通过函数调用来执行。
C语言中,函数有返回值和无返回值的两种类型。
8.结构体:结构体是一种自定义的数据类型,可以包含多个不同类型的成员变量。
9.指针:指针是用来存储内存地址的变量,可以通过指针来访问和修改内存中的数据。
10.文件操作:C语言提供了一系列的文件操作函数,可以对文件进行读写操作。
11.预处理器:C语言中的预处理器指令以#开头,用于在程序编译之前进行一些预处理操作,如宏定义、条件编译等。
12. 头文件和库:头文件是包含一些函数和变量声明的文件,可以通过#include指令引用。
库文件是包含一些函数和变量实现的文件,可以通过链接库来使用其中的函数和变量。
13. 内存管理:C语言中可以通过动态内存分配函数(如malloc、free)来管理内存的分配和释放。
14. 异常处理:C语言中没有内置的异常处理机制,但可以通过返回错误码或使用setjmp和longjmp来实现简单的异常处理。
STM32---学习笔记
/*****************************DATE : 8/20/2010*************************************************************************************************************#include "stm32f10x_lib.h"#include "TFT.h"#define ADC1_DR_Address ((u32)0x4001244C) //ADC1数据寄存器地址ADC_InitTypeDef ADC_InitStructure;DMA_InitTypeDef DMA_InitStructure;vu16 ADCConvertedValue;void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void Num2String(unsigned int Num,unsigned char *Ptr);int main(void){unsigned char AD_CharData[4];//volatile unsigned long data;/* System clocks configuration ---------------------------------------------*/RCC_Configuration();/* NVIC configuration ------------------------------------------------------*/NVIC_Configuration();/* GPIO configuration ------------------------------------------------------*/GPIO_Configuration();TFT_Init();/* DMA1 channel1 configuration ----------------------------------------------*/DMA_DeInit(DMA1_Channel1); //选择通道1DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC1的地址为DMA 的外设基地址DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;//内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据传输的来源DMA_InitStructure.DMA_BufferSize = 1; //DMA缓存大小为1个数据单位DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址寄存器不变DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度为16位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存数据宽度为16位DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA工作在循环缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道1拥有高优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止DMA通道的内存到内存传输,因为这里是外设到内存的传输DMA_Init(DMA1_Channel1, &DMA_InitStructure);/* Enable DMA1 channel1 */DMA_Cmd(DMA1_Channel1, ENABLE);/* ADC1 configuration ------------------------------------------------------*/ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC1工作在独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//工作在连续转换模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件来触发转换启动ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;// ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 1;//顺序进行规则转换的ADC通道数目为1 ADC_Init(ADC1, &ADC_InitStructure);//为了能够正确配置每一个ADC通道,在调用ADC_Init()之后,必须调用ADC_ChannelConfig()//来配置每个所使用通道的转换次序和采样时间/* ADC1 regular channel8 configuration 采样时间为55.5周期*/ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);/* Enable ADC1 DMA */ADC_DMACmd(ADC1, ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable ADC1 reset calibaration register 复位校准寄存器*/ADC_ResetCalibration(ADC1);/* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位完成/* Start ADC1 calibaration 开始校准*/ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));//等待校准完成/* Start ADC1 Software Conversion */ADC_SoftwareStartConvCmd(ADC1, ENABLE); //开始转换//data = ADCConvertedValue*3.3;//data = data/4096;while (1){Num2String(ADCConvertedValue,AD_CharData);Display_RGBw_16bit(0x00,0x00);Display_Ascii_16bit(60,160,"AIN8 V ALUE:",3,0);Display_Ascii_16bit(148,160,AD_CharData,3,0);}}/****************************************************************************** ** Function Name : RCC_Configuration* Description : Configures the different system clocks.* Input : None* Output : None* Return : None******************************************************************************* /void RCC_Configuration(void){ErrorStatus HSEStartUpStatus;/* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);/* Wait till HSE is ready */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* ADCCLK = PCLK2/4 */RCC_ADCCLKConfig(RCC_PCLK2_Div4);/* PLLCLK = 8MHz * 7 = 56 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08){}}/* Enable peripheral clocks --------------------------------------------------*//* Enable DMA1 clock */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE);}/****************************************************************************** ** Function Name : GPIO_Configuration* Description : Configures the different GPIO ports.* Input : None* Output : None* Return : None******************************************************************************* /void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* Configure PB.0 (ADC Channel8) as analog input -------------------------*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOB, &GPIO_InitStructure);/* Configure PD.11--PC.15 as Output push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_9 | GPIO_Pin_8 |GPIO_Pin_7 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOD, &GPIO_InitStructure);/* Configure PE.00 -- PE.15 as Output push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOE, &GPIO_InitStructure);}//int整型数转换成字符串void Num2String(unsigned int Num,unsigned char *Ptr){unsigned char instr[4];unsigned char i=4;unsigned char k;do{instr[--i] = Num%10+'0';Num/=10;}while(Num!=0);for(k=i;k<4;k++){*Ptr++=instr[k];}*Ptr = '\0';}/****************************************************************************** ** Function Name : NVIC_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void NVIC_Configuration(void){#ifdef VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif}#include "stm32f10x_lib.h"void RCC_Configuration(void);void NVIC_Configuration(void);void USART_Config(void);void USART2_Puts(char * str); //输出字符串void USART2_Putc(char c); //输出一个字符unsigned char USART2_ReceiveChar(void); //接收一个字符同时作为是一个函数声明int main(void){RCC_Configuration();NVIC_Configuration();USART_Config();while (1){USART2_Putc(USART2_ReceiveChar());USART2_Puts(USART2_ReceiveChar());}}/****************************************************************************** ** 函数名: RCC_Configuration* 功能: 时钟配置* 输入: 无* 输出: 无* 返回: 无******************************************************************************* /void RCC_Configuration(void){ErrorStatus HSEStartUpStatus;RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);FLASH_SetLatency(FLASH_Latency_2);RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource() != 0x08){}}}void USART_Config(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_ART_BaudRate = 9600;USART_ART_WordLength = USART_WordLength_8b;USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No ;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART2, &USART_InitStructure);USART_Cmd(USART2, ENABLE);}void USART2_Putc(char c){USART_SendData(USART2, c);while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);}void USART2_Puts(char * str){while(*str){USART_SendData(USART2, *str++);while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);}}unsigned char USART2_ReceiveChar(void){while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);return(USART_ReceiveData(USART2));}/****************************************************************************** ** 函数名: NVIC_Configuration* 功能: 中断配置* 输入: 无* 输出: 无* 返回: 无******************************************************************************* /void NVIC_Configuration(void){#ifdef VECT_TAB_RAMNVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#elseNVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif}。
STM32学习笔记二
STM32学习笔记二:1、keil编译的三个按键的功能A、第一个按钮:Translate 就是翻译当下修改过的文件,说明白点就是检查下有没有语法错误,并不会去链接库文件,也不会生成可执行文件。
B、第二个按钮:Build 就是编译当下修改过的文件,它包含了语法检查,链接动态库文件,生成可执行文件。
C、第三个按钮:Rebuild 重新编译整个工程,跟Build 这个按钮实现的功能是一样的,但有所不同的是它编译的是整个工程的所有文件,耗时巨大。
综上:当我们编辑好我们的程序之后,只需要用第二个Build 按钮就可以,即方便又省时。
第一个跟第三个按钮用的比较少2 、core_cm3.c 跟启动文件一样都是底层文件,都是由ARM 公司提供的,遵守CMSIS 标准,即所有CM3 芯片的库都带有这个文件,这样软件在不同的CM3 芯片的移植工作就得以简化。
3、system_stm32f10x.c,是由ST 公司提供的,遵守CMSIS 标准。
该文件的功能是设置系统时钟和总线时钟,system_stm32f10x.c 在实现系统时钟的时候要用到PLL(锁相环),这就需要操作寄存器,寄存器都是以存储器映射的方式来访问的,所以该文件中包含了stm32f10x.h 这个头文件。
4、stm32f10x.h定义寄存器的地址及使用的结构体封装。
5、6、.chm文件在NTFS硬盘中是打不开的,我们需要选中文件,右键属性,然后点击解除锁定即可。
7、USER用来存放工程文件和用户代码,包括主函数main.cFwlib用来存放STM32库里面的inc和src这两个文件,这两个文件包含了芯片上的所有驱动。
CMSIS用来存放库为我们自带的启动文件和一些M3系列通用的文件。
CMSIS 里面存放的文件是适合任何M3内核的单片机。
Output用来保存软件编译后输出的文件。
Listing用来存放一些编译过程中产生的文件,具体可以不用了解。
8、建立工程的一般步骤:a、\3.5.0\3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_Std Periph_Driver 的inc 跟src拷贝到Fwlibb、\3.5.0\3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPe riph_Template main.c 、stm32f10x_conf.h、stm32f10x_it.h、stm32f10x_it.c、system_stm32f10x.c拷贝到USER目录下。
STM32中C语言知识点初学者必看
STM32中C语言知识点初学者必看1. 数据类型:C语言中的数据类型包括整型(int)、字符型(char)、浮点型(float)、双精度浮点型(double)等。
了解每种数据类型的取值范围、内存占用大小以及类型转换等是很重要的。
2.变量和常量:在C语言中,需要使用变量来存储和操作数据。
变量需要先声明,然后才能使用。
常量是不可修改的固定值。
3.运算符:C语言中有多种运算符,如算术运算符(+、-、*、/等)、关系运算符(<、>、==、!=等)、逻辑运算符(&&,!等)等。
了解运算符的用法和优先级是编写正确代码的基础。
4. 控制结构:C语言中的控制结构包括顺序结构、条件结构(if-else语句)和循环结构(while循环、for循环)。
掌握这些结构的语法和使用方法,可以实现不同的程序逻辑。
5.数组:数组是相同数据类型的元素集合。
了解如何声明和使用数组,以及数组的特点和限制是非常重要的。
6.函数:函数是一段完成特定任务的代码块。
通过函数的调用,可以实现代码的重复利用和模块化。
掌握函数的定义、声明和调用的方法是C语言的核心。
7.指针:指针是存储变量地址的变量。
理解指针的概念、指针和数组的关系,以及指针的运算和使用是C语言中的难点。
8.结构体:结构体是一种用户自定义的数据类型,允许存储不同数据类型的元素。
了解如何定义和使用结构体可以更好地组织和管理数据。
9.文件操作:C语言提供了文件操作函数来读取和写入文件。
了解如何打开、关闭、读写文件,以及错误处理是编写具有文件操作功能的程序的基础。
10.预处理指令:预处理指令是在编译之前被预处理器处理的指令,可以用来定义常量、包含头文件、条件编译等。
了解预处理指令的使用可以提高代码的可读性和可维护性。
11. 内存管理:C语言中需要手动管理内存的分配和释放。
了解如何使用malloc函数申请内存,以及使用free函数释放内存是编写高效、稳定程序的要求。
STM32学习 C语言笔记
这是前段时间做彩屏显示时候遇到的难题,*(__IO uint16_t*)(Bank1_LCD_C)这个就是将后面的数据转换为地址,然后对地址单元存放数据。
可如下等效:__IO uint16_t*addr;addr=(__IO uint16_t*)Bank1_LCD_C;#ifdef和#elif连用,语法和if。
else if语句一样推挽输出增加驱动,可以驱动LED起来static int count=0count++这个语句中,count仅仅被初始化一次以后加加一次期中的值就不会变化了SysTick_CTRL(控制和状态寄存器)SysTick_LOAD(重装载寄存器)SysTick_VAL(当前值寄存器)SysTick_CALIB(校准值寄存器)TFT经验:弄多大的相片,必须先把那个相片的尺寸改掉,再去取模,才可以,要不会有重影的嘿嘿嘿嘿VBAT是电池供电的引脚VBAT和ADD同时都掉电时才能让备份区复位。
volatile一个变量的存储单元可以在定义该变量的程序之外的某处被引用。
volatile主要是程序员要告诉编译器不要对其定义的这个变量进行优化,防止其不能被引用,不能被改变。
VDDA>2.4V ADC才能工作VDDA>2.7V USB才能工作VDD(1.8-3.6v)VBAT=1.8-3.6vVSS VSSA VREF必须接到地线没有外部电源供电时必须VBAT接上VDD使用PLL时,VDDA必须供电printf("abs(x)=%d\n",x<0?(-1)*x:x)条件编译是问号前边为真则取冒号前边的值,为假的,则取后边的值。
所以说上边这条打印的语句是打印x的绝对值。
//stm32f10x_nvic.cstm32f10x_lib.cstm32f10x_gpio.cstm32f10x_flash.cstm32f10x_rcc.cTIM6TIM7基本定时器(只有这两个定时器不能产生PWM)TIM1TIM8高级控制定时器TIM2TIM3TIM4TIM5为通用定时器其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。
手把手教你STM32笔记
STM32F1031、IO口处理IO口包含7个寄存器配置寄存器两个:CRL(32),CRH(32)数据寄存器两个:IDR(32),ODR(32),但是他们只用了16位置位复位寄存器:BSRR(32)复位寄存器:BRR(16)锁存寄存器:LCKR(32)常用的有前面四个:其中前面两个是用来设置的,后面两个是用来操作的。
每个IO口占用四位进行设置(低两位是MODE,高两位是CNF),每组16个,总共需要64个位设置,分别从CRL低位开始,到CRH 的高位结束。
每个IO口四位二进制的常用配置:模拟输入模式(ADC):0x0;推挽输出模式(输出口50MHz):0x3;上/下拉输入模式(输入口用):0x8;复用输出(第二供能):0xB;STM32F407学习笔记1、系统时钟的设置:Stm32_Clock_Init(168,4,2,7);参数分别是:PLLN,PLLM,PLLP,PLLQHSE分频PLLM之后为VCO的输入,一般VCO的输入要求为1~2MHz,一般建议取为2MHz,防止PLL抖动。
VCO输出是输入的PLLN倍频,SYSCLK在去PLL输出时,SYSCLK = PLL=HSE/PLLM*PLLN/PLLP而PLLQ是为48MHz时钟配置用的,CLK48= HSE/PLLM*PLLN/PLLQ所以要设置系统时钟为168MHz时候推荐的参数取值为SYSCLK = PLL=HSE/PLLM*PLLN/PLLP =8/4*168/2=168MHzCLK48= HSE/PLLM*PLLN/PLLQ=8/4*168/7=48MHz2、延时函数设置:delay_init(168);延时函数参数为系统时钟SYSCLK初始化后就可以调用延时函数:delay_ms(ms);参数不能大于65536,因为参数是16位数delay_us(us);参数不能大于7989153、普通IO的使用a.首先是使能时钟RCC->AHB1ENR|=1<<5;在该寄存器相应的位置1即可b.IO口模式设置:GPIO_Set(GPIOF,PIN9|PIN10,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD _PU);参数分别是:GPIOx,PIN9|PIN10(具体对应的口,可以使用与的关系)因为每种占一位#define PIN0 1<<0#define PIN1 1<<1#define PIN2 1<<2#define PIN3 1<<3#define PIN4 1<<4#define PIN5 1<<5#define PIN6 1<<6#define PIN7 1<<7#define PIN8 1<<8#define PIN9 1<<9#define PIN10 1<<10#define PIN11 1<<11#define PIN12 1<<12#define PIN13 1<<13#define PIN14 1<<14#define PIN15 1<<15Mode:四种,各个模式只能设置一种#define GPIO_MODE_IN 0 //普通输入模式#define GPIO_MODE_OUT 1 //普通输出模式#define GPIO_MODE_AF 2 //AF功能模式#define GPIO_MODE_AIN 3 //模拟输入模式输出推挽或者开漏选择:#define GPIO_OTYPE_PP 0 //推挽输出#define GPIO_OTYPE_OD 1 //开漏输出推挽输出可输出强的高、低电平,用于连接数字器件开漏输出相当于三极管的集电极,电流型驱动,只可以输出强的低电平,高电平需外拉。
STM32入门C语言详解
阅读flash:芯片内部存储器flash操作函数我的理解——对芯片内部flash进行操作的函数,包括读取,状态,擦除,写入等等,可以允许程序去操作flash上的数据。
基础应用1,FLASH时序延迟几个周期,等待总线同步操作。
推荐按照单片机系统运行频率,0—24MHz时,取Latency=0;24—48MHz时,取Latency=1;48~72MHz时,取Latency=2。
所有程序中必须的用法:FLASH_SetLatency(FLASH_Latency_2);位置:RCC初始化子函数里面,时钟起振之后。
基础应用2,开启FLASH预读缓冲功能,加速FLASH的读取。
所有程序中必须的用法:FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);位置:RCC初始化子函数里面,时钟起振之后。
3、阅读lib:调试所有外设初始化的函数。
我的理解——不理解,也不需要理解。
只要知道所有外设在调试的时候,EWRAM需要从这个函数里面获得调试所需信息的地址或者指针之类的信息。
基础应用1,只有一个函数debug。
所有程序中必须的。
用法:#ifdef DEBUGdebug();#endif位置:main函数开头,声明变量之后。
4、阅读nvic:系统中断管理。
我的理解——管理系统内部的中断,负责打开和关闭中断。
基础应用1,中断的初始化函数,包括设置中断向量表位置,和开启所需的中断两部分。
所有程序中必须的。
用法:void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure; //中断管理恢复默认参数#ifdef VECT_TAB_RAM //如果C/C++ Compiler\Preprocessor\Defined symbols中的定义了VECT_TAB_RAM(见程序库更改内容的表格)NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //则在RAM调试#else //如果没有定义VECT_TAB_RAMNVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//则在Flash里调试#endif //结束判断语句//以下为中断的开启过程,不是所有程序必须的。
stm32学习笔记
STM32学前班教程之一:为什么是它经过几天的学习,基本掌握了STM32的调试环境和一些基本知识。
想拿出来与大家共享,笨教程本着最大限度简化删减STM32入门的过程的思想,会把我的整个入门前的工作推荐给大家。
就算是给网上的众多教程、笔记的一种补充吧,所以叫学前班教程。
其中涉及产品一律隐去来源和品牌,以防广告之嫌。
全部汉字内容为个人笔记。
所有相关参考资料也全部列出。
教程会分几篇,因为太长啦。
今天先来说说为什么是它——我选择STM32的原因。
我对未来的规划是以功能性为主的,在功能和面积之间做以平衡是我的首要选择,而把运算放在第二位,这根我的专业有关系。
里面的运算其实并不复杂,在入门阶段想尽量减少所接触的东西。
不过说实话,对DSP的外设并和开发环境不满意,这是为什么STM32一出就转向的原因。
下面是我自己做过的两块DSP28的全功能最小系统板,在做这两块板子的过程中发现要想尽力缩小DSP的面积实在不容易(目前只能达到50mm×45mm,这还是没有其他器件的情况下),尤其是双电源的供电方式和1.9V的电源让人很头疼。
后来因为一个项目,接触了LPC2148并做了一块板子,发现小型的ARM7在外设够用的情况下其实很不错,于是开始搜集相关芯片资料,也同时对小面积的AVR和51都进行了大致的比较,这个时候发现了CortexM3的STM32,比2148拥有更丰富和灵活的外设,性能几乎是2148两倍(按照MIPS值计算)。
正好2148我还没上手,就直接转了这款STM32F103。
与2811相比较(核心1.8V供电情况下),135MHz×1MIPS。
现在用STM32F103,72MHz×1.25MIPS,性能是DSP的66%,STM32F103R型(64管脚)芯片面积只有2811的51%,STM32F103C型(48管脚)面积是2811的25%,最大功耗是DSP的20%,单片价格是DSP的30%。
STM32学习笔记
2011年1月15日星期六SysTick 是MDK定义了的一个结构体(在stm32f10x_map.里面),里面包含CTRL、LOAD、VAL、CALIB 等4 个寄存器,我自己理解为要是使用systick时钟是肯定要对这个寄存器进行设置的。
具体到什么事寄存器什么为什么内部会是这个样子,那我就不得而知了但是我懂得这个是配置必须的东西而且这个寄存器是被mdk定义为了一个结构体stm32f10x_map今天算是又学到了一招利用mdk 里边右键里面有一个go to definition 可以跟踪到这个元素的初始的位置,就相当于是找到它最为原始的定义。
然后找到了一些个U8 u16 u32 等等的含义哈哈原来STM32就是如此的简单当然群里的威力也是很大的。
typedef signed long s32;typedef signed short s16;typedef signed char s8;typedef signed long const sc32; /* Read Only */typedef signed short const sc16; /* Read Only */typedef signed char const sc8; /* Read Only */typedef volatile signed long vs32;typedef volatile signed short vs16;typedef volatile signed char vs8;typedef volatile signed long const vsc32; /* Read Only */typedef volatile signed short const vsc16; /* Read Only */typedef volatile signed char const vsc8; /* Read Only */typedef unsigned long u32;typedef unsigned short u16;typedef unsigned char u8;typedef unsigned long const uc32; /* Read Only */typedef unsigned short const uc16; /* Read Only */typedef unsigned char const uc8; /* Read Only */typedef volatile unsigned long vu32;typedef volatile unsigned short vu16;typedef volatile unsigned char vu8;typedef volatile unsigned long const vuc32; /* Read Only */typedef volatile unsigned short const vuc16; /* Read Only */typedef volatile unsigned char const vuc8; /* Read Only */2011年1月16日星期日void delay_us(u32 nus){u32 temp;SysTick->LOAD=nus*fac_us; //时间加载SysTick->VAL=0x00; //清空计数器SysTick->CTRL=0x01 ; //开始倒数do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//等待时间到达SysTick->CTRL=0x00; //关闭计数器SysTick->VAL =0X00; //清空计数器}我现在有点不明白CTRL之前设置的有相应的选择,为什么这个地方只要第0位置位就行了,而不需要相应的其他设置了,比较郁闷但是后便的不难理解,首先do-while语句就是先执行do{}内的内容,再判断while{}内的内容,如果while中的内容为非0,则再返回do{}内执行,再判断while{},直到while{}内部条件按为0,跳出循环。
STM32中C语言知识点初学者必看
STM32中C语言知识点初学者必看1.基本数据类型:学习C语言的基本数据类型,如整型、浮点型、字符型、布尔型等。
了解它们在STM32中的表示方式和存储要求。
2. 控制语句:学习C语言的控制语句,如条件判断语句(if-else语句)、循环语句(for循环、while循环)和跳转语句(break、continue、return)。
了解它们在STM32中的应用场景和注意事项。
3.数组和指针:掌握C语言中的数组和指针的概念和使用方法。
了解如何在STM32中使用数组和指针进行数据存储和访问,以及如何进行数组和指针的参数传递。
4.函数:学习C语言函数的定义和调用方式。
了解如何在STM32中编写和调用函数,并掌握函数参数传递和返回值的使用方法。
5.结构体和联合体:了解C语言中结构体和联合体的定义和使用方法。
掌握在STM32中创建和使用结构体和联合体的技巧。
6.文件操作:学习如何在STM32中进行文件操作,如打开、读取和写入文件。
了解如何操作存储器设备(如SD卡)来读写文件。
7.中断:了解STM32中的中断机制和中断处理函数的编写方法。
学习如何配置和处理外部中断、定时器中断和串口中断等。
8.串口通信:学习如何在STM32中进行串口通信。
掌握如何配置和使用串口设备,并使用串口进行数据的发送和接收。
9.GPIO操作:了解STM32中的GPIO引脚配置和操作方法。
掌握如何配置和操作GPIO引脚以实现输入和输出功能。
10.PWM输出:学习如何使用STM32的定时器来实现PWM输出。
了解如何配置定时器和通道以产生PWM信号,并掌握调节占空比和频率的方法。
11.RTC实时时钟:了解STM32中的实时时钟模块(RTC)的配置和使用方法。
学习如何设置和读取当前时间,并使用RTC进行定时操作。
12.ADC模数转换:学习如何使用STM32的模数转换模块(ADC)来进行模拟信号的转换。
掌握如何配置ADC和通道,以及如何读取和处理模拟输入信号。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
这是前段时间做彩屏显示时候遇到的难题,
*(__IO uint16_t *) (Bank1_LCD_C)这个就是将后面的数据转换为地址,然后对地址单元存放数据。
可如下等效:
__IO uint16_t *addr;
addr = (__IO uint16_t *) Bank1_LCD_C;
#ifdef和#elif连用,语法和if。
else if语句一样
推挽输出增加驱动,可以驱动LED起来
static int count=0
count++
这个语句中,count仅仅被初始化一次
以后加加一次期中的值就不会变化了
SysTick_CTRL(控制和状态寄存器)
SysTick_LOAD(重装载寄存器)
SysTick_VAL(当前值寄存器)
SysTick_CALIB(校准值寄存器)
TFT经验:弄多大的相片,必须先把那个相片的尺寸改掉,再去取模,才可以,要不会有重影的嘿嘿嘿嘿
VBAT 是电池供电的引脚
VBAT和ADD同时都掉电时才能让备份区复位。
volatile一个变量的存储单元可以在定义该变量的程序之外的某处被引用。
volatile主要是程序员要告诉编译器不要对其定义的这个变量进行优化,防止其不能被引用,不能被改变。
VDDA>2.4V ADC才能工作
VDDA>2.7V USB才能工作
VDD(1.8-3.6v)
VBAT=1.8-3.6v
VSS VSSA VREF必须接到地线
没有外部电源供电时必须VBAT接上VDD
使用PLL时,VDDA必须供电
printf("abs(x)=%d\n",x<0?(-1)*x:x)
条件编译是问号前边为真则取冒号前边的值,为假的,则取后边的值。
所以说上边这条打印的语句是打印x的绝对值。
//stm32f10x_nvic.c
stm32f10x_lib.c
stm32f10x_gpio.c
stm32f10x_flash.c
stm32f10x_rcc.c
TIM6 TIM7基本定时器
(只有这两个定时器不能产生PWM)
TIM1 TIM8高级控制定时器
TIM2 TIM3 TIM4 TIM5为通用定时器
其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。
而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出!
修改和自己写代码时候
只是需要修改
main.c
stm3210x_conf.h
stm3210x_it.c
这三个就够了
1:BOOT0接高电平的时候容易自动复位
2:BOOT0接0的时候用户闪存存储器为启动区域
3:BOOT0接1的BOOT1接0的时候用户用系统存储器或内嵌SRAM, 这时候容易自动复位。
4:我的板子是boot0接1,boot1接0,也就是系统存储器为启动区域
使用code这个关键字就能使数据烧写到flash中了
ram类似于电脑中的内存
flash类似硬盘。