OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
12
返回列表 发新帖
楼主: 初心永恒

改正以往的学习方法,按实验重新学习,在此发帖;分享自己做的笔记,也督促自己坚持下去。持之以恒!!!

[复制链接]

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-10-31 22:07:56 | 显示全部楼层
第十二天ADC实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
STM32ADC12位逐次逼近型的模拟数字转换器,有18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。STM32ADC的转换分为两个通道组:规则通道组和注入通道组。规则通道相当于正常运行的程序,而注入通道就相当于中断。

STM32ADC的主要特征:12位分辨率、转换结束、注入转换结束和发生模拟看门狗事件时产生中断、单次和连续转换模式、从通道0到通道n的自动扫描模式、自校准、带内嵌数据一致性的数据对齐、采样间隔可以按通道分别编程、规则转换和注入转换均有外部触发选项、间断模式、双重模式(2个或以上ADC的器件)ADC转换时间:     STM32F103xx增强型产品:时钟为56MHz时为1μs(时钟为72MHz1.17μs)ADC供电要求:2.4V3.6VADC输入范围:VREF- V IN V REF+、规则通道转换期间有DMA请求产生。(注:《STM32中文参考手册》是个好参考)。

单次转换模式:一旦选择的通道转换完成,转换结果被存放在相应寄存器中,转换结束标志位被置位,如果使能了中断,则产生中断,ADC停止,等待下一次启动。

ADC初始化:
①    开启PA0ADC1时钟,设置PA0为模拟输入。
RCC_APB2PeriphClockCmd();
GPIO_Init();
关于ADC通道与GPIO对应,见参考手册。
②    复位ADC,设置ADC分频因子
ADC_DeInit(ADC1);//复位指定ADC
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
③    初始化ADC参数

ADC控制寄存器ADC_CR1ADC_CR2ADC_CR1的位8SCAN位,用于设置扫描模式;ADC_CR1的位[19:16]DUALMOD,用于设置ADC的操作模式;ADC_CR2的位1CONT位用于设置是否进行连续转换;ADC_CR2的位11ALIGN位用于设置数据对齐方式;ADC_CR2的位[19:17]EXTSEL位用于选择启动规则转换组转换的外部事件,共八种,这里选用软件触发(111)。
ADC1ADC2的触发配置如下:
000:定时器1TRGO事件  100:定时器3CC4事件
001:定时器1CC4事件  101:定时器4TRGO事件
110EXTI线15/TIM8_CC4事件(仅大容量产品具
TIM8_CC4)
010:定时器2TRGO事件
011:定时器2CC1事件  111JSWSTART
ADC3的触发配置如下
000:定时器1TRGO事件  100:定时器8CC4事件
001:定时器1CC4事件  101:定时器5TRGO事件
010:定时器4CC3事件  110:定时器5CC4事件
011:定时器8CC2事件  111JSWSTART

ADC规则序列寄存器ADC_SQR1~31~3差不多),位[23:20]L—设置规则通道序列长度;其它的SQ存储了规则序列中通道的编号。
ADC_Init(ADC1,&ADC_InitStructure);
typedef struct
{

uint32_t ADC_Mode;//设定ADC的模式

FunctionalState ADC_ScanConvMode;//是否开启扫描模式

FunctionalState ADC_ContinuousConvMode;//是否开启连续转化模式

uint32_t ADC_ExternalTrigConv;//启动规则转换组转换的外部事件

uint32_t ADC_DataAlign;//ADC数据对齐方式

uint8_t ADC_NbrOfChannel;//设置规则序列长度

}ADC_InitTypeDef;
④    使能ADC并校准(到这里,初始化就完成了)

ADC_CR2的位0ADON位用于开关ADC转换器,ADC_CR2的位2RSTCAL,用于复位校准;ADC_CR2的位3CAL,用于AD校准;

ADC状态寄存器ADC_SR:位4STRT位,规则通道开始位;位3JSTRT,注入通道开始位;位0AWD,模拟看门狗标志位

使能ADC{ADC_Cmd(ADC1,ENABLE);}然后—>
复位校准{ ADC_StartCalibration(ADC1);}然后—>
等待复位校准结束{ while(ADC_GetSoftwareStartConvStatus(ADC1));}然后—>执行ADC校准{ ADC_ResetCalibration(ADC1);}然后—>
等待校准完成{ while(ADC_GetResetCalibrationStatus(ADC1));}
读取ADC值:
①    设置规则序列通道以及采样周期

ADC采样事件寄存器ADC_SMPR1ADC_SMPR2,用于设置通道0~17的采样时间,每个通道占用三个位。ADC的转换时间公式:Tcovn=采样时间+12.5个周期,Tcovn为总转换时间。

ADC_RegularChannelConfig(ADCx,ADC_Channel,Rank,ADC_SampleTime);//ADCxchx,序列,采样周期。
②    开启ADC转换

ADC规则数据寄存器,规则序列中A/D转换结果被存放在这个寄存器里面,注入通道的转换结果被保存在ADC_JDRx里面。

ADC_SoftwareStartConvCmd(ADC1,ENABLE);
③    等待转换完成,获取ADC转换结果数据

ADC_SR的位2JEOC,注入通道转换结束位;ADC_SR的位1EOC,转换结束位。

while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换完成
ADC_GetConversionValue(ADC1);//获取转换结果数据
      
       STM32F103ZET6有外部参考电压Vref-(必须和VSSA连接在一起)和Vref+(输入范围为2.4~VDDA

       要使用的固件库函数有stm32f10x_adc文件。
                                                                                                                       1031

正点原子逻辑分析仪DL16劲爆上市
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-1 17:41:01 | 显示全部楼层
第十三天DAC实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
实验目的:使用DAC通道1来输出电压,使用按键来控制电压输出增/减,通过ADC1的通道1采集DAC的输出电压,将数据显示在LCD显示屏上。



STM32模块的主要特点:
l       2DAC转换器,每个转换器对应一个输出通道。
l       8位或23位单调输出
l       12位模式下数据左对齐或者右对齐
l       同步更新功能
l       噪声波形生成
l       三角波形生成
l       DAC通道同时或分别转换
l       每个通道都由DMA功能

DAC输出是受DORx寄存器直接控制的,但是不能直接往DORx寄存器写入数据,而是通过DHRx间接的传给DORx寄存器。
DACx的输出电压=VREFDORx/4095


配置DAC的步骤如下:
①   开启PA口时钟,设置PA4DAC的通道1)为模拟输入
因为使能DACx通道之后,相应的GPIO引脚会自动与DAC的模拟输出相连,设置为输入,是为了避免额外的干扰。
RCC_APB2PeriphClockCmd();GPIO_Init();
②   使能DAC1时钟
RCC_APB1PeriphClockCmd();
③   初始化DAC,设置DAC的工作模式

DAC控制寄存器DAC_CR(32),低16位控制通道1,高16位控制通道2。低16位与高16位一样,介绍低16位。
12DMAEN1,通道1DMA使能位;位[11:8]MAMP,通道1的屏蔽/幅值选择器;位[7:6]MAVE1,噪声/三角波生成使能;位[5:3]TSEL1,触发选择位;位2TEN1,触发使能位,0:关闭,写入寄存器DAC_DHRx的数据在一个APB1时钟周期后传入寄存器DAC_DOR1,1:开启,写入寄存器DAC_DHRx的数据在三个APB1时钟周期后传入寄存器DAC_DOR1中(如果选择软件触发,则也是一个时钟周期);位1BOFF1,关闭输出缓存;位0EN1DAC通道1使能。

DAC_Init();


typedef struct
{
  uint32_tDAC_Trigger; //设置是否使用触发功能
  uint32_tDAC_WaveGeneration;//设置是否使用波形发生
  uint32_tDAC_LFSRUnmask_TriangleAmplitude;//设置屏蔽/幅值选择器
  uint32_tDAC_OutputBuffer;//设置输出缓存位
}DAC_InitTypeDef;// DAC_Init();使用的结构体

④   使能DAC转换通道
DAC_Cmd();
⑤   设置DAC的输出值
DAC_SetChannel1Data(a,b);//第一个为对齐方式,第二个为DAC的输出值
DAC_GetDataOutputValue(DAC_Channel_1);//读出DAC的数值

数据保存寄存器DAC_DHR,不在这里记录了。
  
使用的固件库函数在stm32f10x_dac文件中
                                                                                                                     111

回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-2 21:31:55 | 显示全部楼层
第十四天DMA实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
目的:在上一个实验的基础上,利用DMA实现串口数据传送,并在LCD上显示当前传输的进度,使用led1作为指示灯。

DMA,即直接存储器访问,将数据从一个地址空间复制到另外一个地址空间。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAMI/O设备开辟一条直接传送数据的通路,能使CPU的效率大大提高。STM32DMA有以下一些特性:
l       每个通道都直接连接专用的硬件DMA请求,都支持软件触发。
l       在七个请求间的优先权可以通过软件编程设置(共有4级,很高、高、中等和低),假如在相等优先权时由硬件决定。
l       独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。
l       支持循环的缓冲器管理。
l       每个通道都由3个事件标志(半传输、传输完成、传输出错),这三个事件标志逻辑或成为一个单独的中断请求。
l       存储器和存储器间的传输。
l       外设和存储器,存储器和外设的传输。
l       闪存、SRAM、外设的SRAMAPB1APB2AHB外设均可以作为访问的源和目标。
l       可编程的数据传输数目:最大为65536

从外设产生的DMA请求,通过逻辑或输入到DMA控制器,同时只有一个请求有效。外设的DMA请求可以通过设置相应的外设寄存器中的控制位独立开启或关闭,需要的时候可以查参考手册。
DMA1通道4的配置步骤:
①   使能DMA时钟
RCC_AHBPeriphClockCmd();
②   初始化DMA通道x的参数

DMA通道x配置寄存器DMA_CCRx(32)
14MEM2MEM:存储器到存储器模式;
[13:12]PL[1:0]:通道优先级;
[11:10]MSIZE[1:0]:存储器数据宽度;
[9:8]PSIZE[1:0]:外设数据宽度;
7MINC:存储器地址增量模式;
6PINC:外设地址增量模式;
5CIRC:循环模式;
4DIR:数据传输方向;
3TEIE:允许传输错误中断;
2HTIE:允许半传输中断;
1TCIE:允许传输完成中断;
0EN:通道开启。

DMA_Init();//使用结构体
typedef struct
{
  uint32_tDMA_PeripheralBaseAddr;//设置DMA传输的外设的基地址
uint32_t DMA_MemoryBaseAddr;//内存基地址(也就是存放DMA传输数据的内存地址)
uint32_t DMA_DIR;//设置数据的传输方向,外设是源地还是目的地
uint32_t DMA_BufferSize;//设置一次传输数据量的大小
uint32_t DMA_PeripheralInc;//设置传输数据时候的外设地址是否递增
uint32_t DMA_MemoryInc;// 设置传输数据时候的内存地址是否递增
uint32_t DMA_PeripheralDataSize;//设置外设的数据长度是为字节传输(8bits)、半字节(16bits)还是字传输(32bits
uint32_t DMA_MemoryDataSize;//设置内存的数据长度,同上。
uint32_t DMA_Mode;//设置DMA模式是否循环采集
uint32_t DMA_Priority;//设置DMA通道的优先级
              uint32_t DMA_M2M;//设置是否是存储器到存储器模式的传输
         }DMA_InitTypeDef;
③   使能DMA发送

DMA通道x的外设地址寄存器DMA_CPARx,用来存储STM32外设的地址,要使用哪个外设,就要写入相应外设的地址。

DMA通道x存储器地址寄存器DMA_CMARx,用来存放存储器的地址,比如要使用数组来组存储器,那么就写入数组的地址。

USART_DMACmd();//开启串口的DMA,还有其他的,参考资料。
④   使能DMA1通道,启动传输

如果已经进行过了一次传输,需要关闭通道,再设置DMA缓存,然后再一次使能通道,不能少一步,否则无法进行传输。(我自己的理解。)
DMA_SetCurrDataCounter(DMAx_Channeln,DMA1_LEN);//设置缓存长度
DMA_Cmd();
⑤   查询DMA传输状态

中断状态寄存器DMA_ISR32位),若开启了相应的中断位,达到相应条件后会产生中断,也可以通过该寄存器获取DMA传输的状态。位272319151173TEIFx:通道x的传输错误标志位;位262218141062HTIFx:通道x的半传输标志位;位25211713、、951TCIFx:通道x的传输完成标志位;位24201612840位—GIFx:通道x的全局中断标志位。

DMA中断标志清楚寄存器DMA_IFCR,用来清除DMA_ISR的对应位,位数对应一样。

DMA通道x传输数据量寄存器DMA_CNDTRx32位),控制DMA通道x每次传输所要传输的数据量,设置范围位0~65535,该寄存器的值会随着传输的进行而递减,可以得到当前DMA传输的进度。

DMA_GetFlagStatus();//查询DMA传输通道的状态
DMA_GetCurrDataCounter();//获取当前剩余数据量大小
   DMA_ClearFlag();//清除标志位

DMA相关的库函数文件是stm32f10x_dma
弱弱的问一下,有人看我发的帖子么
                                                                                                                     112

回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
26
金钱
26
注册时间
2014-3-21
在线时间
1 小时
发表于 2016-11-2 22:35:45 | 显示全部楼层
大兄弟,请继续保持更新,我刚看见你的帖子,以前也学的粗糙,现在也准备像你这样学习,正在仔细看……
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-3 20:46:23 | 显示全部楼层
电子小蜗牛 发表于 2016-11-2 22:35
大兄弟,请继续保持更新,我刚看见你的帖子,以前也学的粗糙,现在也准备像你这样学习,正在仔细看……

谢谢支持,有人看 我就会一直坚持下去的。
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-3 20:46:48 | 显示全部楼层
初心永恒 发表于 2016-11-3 20:46
谢谢支持,有人看 我就会一直坚持下去的。

会继续上传到这里
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-3 21:35:08 | 显示全部楼层
第十五天IIC实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

  实验目的,在上一个实验的基础上,利用普通I/O口模拟IIC时序实现和2402之间的双向通信,按WK_UP键来执行发送数据,按KEY1来读取数据(这和DAC的按键不冲突),并将结果显示在LCD上。

  IIC总线是一种两线式串行总线,用于连接微控制器及其外围设备,由数据线SDA和时钟SCL构成串行总线,可发送和接收数据。
IIC总线在传输数据过程中共有三种类型信号:
l       开始信号(必需):SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据
l       结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据。
l       应答信号:接收数据的IC在收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。

总结一下IIC的使用:
l       时序图很重要,根据时序图来。!!!这里重要的是开始信号和结束信号、应答信号、2402字节写/读时序,这4个图。
l       IIC发送数据的时候将SCL拉低,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。



l       2402字节写时序分析:开始—>写入数据地址—>写入数据—>停止;在这每一步后都要等待应答信号,以便知道你要做的事情达没达成


开始和结束

开始和结束


应答

应答


2402写

2402写


2402读

2402读





113

回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-3 21:38:31 | 显示全部楼层
  今天的实验记录的比较少,大部分时间都用在读程序、写程序上了。注释程序的每一句话——有助于理解和帮助自己学习。重要的是自己又学习了一些东西,这很好。
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-4 21:09:23 | 显示全部楼层
第十六天SPI实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

SPI:串行外围设备接口,高速、全双工、同步的通信总线。主要应用在EEPROMFlash、实时时钟、A/D转换器、数字信号处理器和数字信号解码器之间。写操作和读操作是同步完成的。
SPI接口一般使用4条线通信:
l       MISO:主设备数据输入,从设备数据输出。
l       MOSI:主设备数据输出,从设备数据输入。
l       SCLK:时钟信号,由主设备产生。
l       CS:从设备片选信号,由主设备控制
  SPI主要特点由:可以同时发出和接收串行数据,可以当作主机或从机工作,提供可编程时钟,发送结束中断标志,写冲突保护,总线竞争保护等。

SPI2的配置步骤:
①   配置相关引脚(PB131415)的复用功能,使能SPI时钟

RCC_APB2PeriphClockCmd();//PORTB时钟使能
RCC_APB1PeriphClockCmd();//SPI时钟使能
GPIO_Init();//设置相关引脚为复用推挽输出。

②   初始化SPI,设置SPI工作模式

SPI_Init();//初始化SPI,使用结构体

typedef struct
{
  uint16_tSPI_Direction;//设置SPI的通信方式
uint16_t SPI_Mode;//设置SPI的主从模式
         uint16_tSPI_DataSize;//8/16位帧格式选择项
         uint16_tSPI_CPOL;//设置时钟极性,时钟极性对传输协议没有重大影响,如果CPOL=0,串行同步时钟的空闲状态为低电平;CPOL=1,串行同步时钟的空闲状态为高电平。SPI主从设备时钟极性和相位应该一致。
         uint16_tSPI_CPHA;//时钟相位,能够选择两种不同的传输协议之一进行数据传输,CPHL=0,在串行同步时钟的第一个跳变沿数据被采样;CPHL=1,在串行同步时钟的第二个跳变沿数据被采样。
         uint16_tSPI_NSS;//设置NSS信号有硬件(NSS引脚)还是软件控制
         uint16_tSPI_BaudRatePrescaler;//设置SPI波特率预分频值。
         uint16_tSPI_FirstBit;//设置数据的传输顺序(高位/低位在前)。
         uint16_tSPI_CRCPolynomial;//设置CRC校验多项式,提高通信可靠性。
       }SPI_InitTypeDef;

③   使能SPI
SPI_Cmd();//使能之后就可以开始SPI通信了,初始化完成。
④   SPI传输数据
SPI_I2S_SendData(SPIx,DATA)//发送数据
SPI_I2S_ReceiveData(SPIx);//接收数据
⑤   查看SPI传输状态
SPI_I2S_GetFlagStatus(SPInxxx);//用来判断SPInxxx的状态

要使用的库函数文件是stm32f10x_spi相关文件。
今天室友过生日,出去吃饭喝酒,所以状态不是很好,只进行了实验,记得东西比较少。算是偷懒吧。。。。

                                                                                                                         114

回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-5 13:51:31 | 显示全部楼层
第十七天RS485实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

RS485,一般称作485/EIA485,隶属于OSI模型物理层,只是物理层的一个标准,典型的串行通讯标准,定义了电压,阻抗等,但不对软件协议给予定义。电气特性规定位2线,半双工,多点通信的标准。
电气特性:逻辑“1”以两线间的电压差位+2~6V表示;逻辑“0”以两线间的电压差位-2~6V表示;电平与TTL电平兼容,方便与TTL电路连接。
其特点包括:
l       接口电平低,不易损坏芯片。
l       传输速率高。
l       抗干扰能力强,接口采用平衡器驱动器和差分接收器的组合。
l       传输距离远,支持节点多。
RS485推荐使用在对点网络,线性网络,总线型网络,不能是星型、环行网络。理想情况下,RS485需要两个匹配电阻(一般为120欧姆),一般加在总线的起止端。
                                                                                                                     115


回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-6 22:03:47 | 显示全部楼层
CAN的实验,遇到了问题,还在学习中,笔记明天一起记录。。。。。。。。。。。
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-7 20:53:52 | 显示全部楼层
第十八、十九天CAN通信实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

CAN,是IOS国际标准化的串行通信协议。CAN控制器根据两根线上的电位差来判断总线电平(显性或隐形)。CAN协议具有的特点:
l       多主控制。在总线空闲时,所有单元都可以发送消息,而两个以上的单元同时发送消息时,根据标示符(ID)决定优先级。
l       系统的柔软性。与总线相连的单元没有“类似于地址”的信息。所以,在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。
l       通信速度较快,通信距离远
l       具有错误检测、错误通知和错误恢复功能。
l       故障封闭功能。CAN可以判断除错误的类型是总线上的暂时的数据错误还是持续的数据错误(发生故障的单元从总线上被隔离出去)。
l       连接节点多。受总线上的时间延迟及电器负载的限制,通信速度越快,可连接的单元越少。
  CAN特别适合工业过程监控设备的互联,公认为最有前途的现场总线之一。

  CAN协议通过:数据帧、遥控帧、错误帧、过载帧、帧间隔,五种类型的帧进行。数据帧和遥控帧有标准格式和扩展模式。
数据帧一般由7个段构成:
l       帧起始,数据开始的段:一个位的显性电平。
l       帧仲裁,帧优先级的段:标准格式的ID11个位,从ID28~ID18被依次发送。禁止高7位都为隐形;扩展格式的ID29个位,基本ID和标准格式的一样;其中,RTR位用于标识是否使用远程帧;IDE位为标识符选择位,SRR位为代替远程请求位,为隐形位。
l       控制段,数据的字节数即保留位的段:由6个位组成,前两位r0r1为保留位,必须以显性电平发送,接收端随意;后四位DLC段为数据长度的表示段,0~8有效,9~15无效,但是不认为是错误。
l       数据段,数据的内容,一帧为0~8个字节的数据。
l       CRC段,检查帧的传输错误的段:由15个位的CRC书序和一个位的CRC界定符(用于分隔)组成;CRC的值计算范围包括帧起始、仲裁段、控制段、数据段,发送和接收双方以同样的算法计算CRC值并进行比较,不一致的时候会通报错误。
l       ACK段,确认正常接收的段:由ACK SlotACK界定符2个位组成,发送单元的ACK发送2个位的隐形位,接收到正确消息的单元在ACK Slot发送显性位,通知发送单元正常接收结束。
l       帧结束,数据帧结束的段:7个位的隐形位。
  由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位可分为4段,这些段又由可称为Tq的最小时间单位构成,各段的作用:
l       同步段SS多个连接在总线上的单元通过此段实现时序调整,同步进行接收和发送工作,跳变沿最好出现在此段上。(1Tq
l       传播时间段PTS用于吸收网络上的物理延迟的段;所谓的物理延迟指发送单元的输出延迟、总线上的信号传播延迟、接收单元的输入延迟。这个段的时间为以上各延迟时间之和的两倍。(1~8Tq
l       相位缓冲段1PBS1当信号边沿不能被包含于SS段中时,可在此段进行补偿;通过相应位缓冲段加减SJW吸收的误差,SJW加大后允许误差加大,但通信速度减慢。(1~8Tq
l       相位缓冲段2PBS2同上。(2~8Tq),前四个加一起为8~25Tq
l       再同步补偿宽度SJW因时钟频率偏差、传送延迟等,各单元有同步误差,SJW为补偿此误差的最大值。(1~4Tq
  在总线空闲态,最开始发送消息的单元获得发送权。当多个单元同时发送时,各发送单元从仲裁段的第一位开始仲裁。连续输出显性电平最多的单元可继续发送,获得总线使用权。

  STM32CAN控制器:
bxCAN—基本扩展CAN,设计目标是以最小的CPU负荷来高效处理大量收到的报文。支持报文发送的优先级要求,提供所有支持时间触发通信模式所需的硬件功能。主要特点有:
l       支持CAN协议2.0A2.0B主动模式。
l       波特率最高达1Mbps
l       支持时间触发通信。
l       具有3个发送邮箱。
l       具有3级深度的两个接收FIFO
l       可变的过滤器组(最多28个)。
  STM32的标示符过滤比较复杂,它的存在减少了CPU处理CAN通信的开销。一个过滤器组由两个32位寄存器(CAN_FxR1CAN_FxR2)组成。
  每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:
              一个32位过滤器:包括STDID[10:0]EXTID[17:0]IDERTR位。
              216位过滤器,包括STDID[10:0]EXTID[17:15]IDERTR位。
  过滤器可配置为屏蔽位模式(标识符寄存器和屏蔽寄存器一起指定的报文标识符的任意一位,应该按照“必须匹配”或“不用关心”处理)和标识符列表模式(屏蔽寄存器也被当做标识符寄存器用,因此不是采用一个标识符加一个屏蔽位的方式,而是使用两个标识符寄存器。)。接受报文标识符的每一位都必须跟过滤器标识符相同。
  通过CAN_FMR寄存器可以配置过滤器组的位宽和工作模式。为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式;为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。应用程序不用的过滤器组应该保持在禁用的状态。
l       CAN发送流程:
1.       为程序选择一个空置的邮箱
2.       设置标识符(ID)、数据长度和发送数据
3.       设置CAN_TIxRTXRQ1,请求发送
4.       邮箱挂号(等待成为最高优先级)
5.       预定发送(等待总线空闲)
6.       发送
7.       邮箱空置
其中还有不强制退出发送(ABRQ=1)和发送失败处理等等。
l       CAN接收流程:
CAN接收到的有效报文被存储在3级邮箱深度的FIFO中,FIFO完全由硬件来管理,节省了CPU的处理负荷,简化了软件并保证了数据的一致性,应用程序只能通过读取FIFO输出邮箱来读取FIFO中最先收到的报文。
1.       FIFO
2.       收到有效报文
3.       挂号1(存入FIFO的一个邮箱,有硬件控制)
4.       收到有效报文
5.       挂号2
6.       ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
7.       直到溢出
每读出一个报文,挂号就减1,如果一直没有读,那么就会导致FIFO溢出,使报文丢失。FIFO接收到的报文数可以通过查询CAN_RFxRFMP寄存器得到。

STM32CAN位时间特性:一个位只有三个段(将传播时间段和相位缓冲段1合并了),同步段(SYNC_SEG1Tq)、时间段1BS1TBS1)和时间段2BS2TBS2)。波特率=正常的位时间的倒数;正常的位时间=Tq+tBS1+tBS2;其中:tBS1=TqTS[3:0]+1),tBS2=TqTS[2:0]+1),Tq=BRP[9:0]+1tPCLK这里Tq表示一个时间单位,tPCLK表示APB时钟的时间周期,BRP[9:0]TS1[3:0]TS2[2:0]CAN_BTR寄存器中定义。


回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-7 20:54:45 | 显示全部楼层
CAN的一般配置步骤:

配置相关引脚的复用功能,使能相应时钟
       RCC_APBnPeriphClockCmd();//使能CANGPIOA时钟
  GPIO_Init();//配置PA11为上拉输入(CAN_RX),PA12位复用输出(CAN_TX
设置CAN工作模式及波特率等
      
       CAN的主控制寄存器CAN_MCR32位),高16位保留,[14:8]位保留
l        16DBF,调试冻结位;0:在调试时,CAN照常工作1:在调试时,冻结CAN的接收/发送。仍然可以正常地读写和控制接收FIFO。
l        15RESET, bxCAN软件复位;0:本外设正常工作;1:对bxCAN进行强行复位,复位后bxCAN进入睡眠模式(FMP位和CAN_MCR寄存器被初始化为其复位值)。此后硬件自动对该位清’0’。
l        7TTCM,时间触发通信模式;1:开启;0:关闭。
l        6ABOM,自动离线(Bus-Off)管理,决定CAN硬件在什么条件下可以退出离线状态。0:离线状态的退出过程是,软件对CAN_MCR寄存器的INRQ位进行置’1’随后清’0’后,一旦硬件检测到128次11位连续的隐性位,则退出离线状态;1:一旦硬件检测到128次11位连续的隐性位,则自动退出离线状态。
l        5AWUM,自动唤醒模式;决定CAN处在睡眠模式时由硬件还是软件唤醒;0:睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒;1:睡眠模式通过检测CAN报文,由硬件自动唤醒。唤醒的同时,硬件自动对CAN_MSR寄存器的SLEEP和SLAK位清0。
l        4NART,禁止报文自动重传;1:CAN报文只被发送1次,不管发送的结果如何;0:0:按照CAN标准,CAN硬件在发送报文失败时会一直自动重传直到发送成功。
l        3RFLM,接收FIFO锁定模式;0:在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文;1:在接收溢出时FIFO被锁定,当接收FIFO的报文未被读出,下一个收到的报文会被丢弃。
l        2TXFP,发送FIFO优先级;当有多个报文同时在等待发送时,该位决定这些报文的发送顺序0:优先级由报文的标识符来决定;1:优先级由发送请求的顺序来决定。
l        1SLEEP,睡眠模式请求。
l        0INRQ,初始化请求位。

CAN位时序寄存器CAN_BTR32位),位[29:26][23][15:10]保留;
l        31SILM,静默模式(用于调试)。
l        30LBKM,环回模式(用于调试)。
l        [25:24]SJW[1:0], 重新跳跃宽度,CAN硬件在每位中可以延长或缩短多少个时间单位,tBJW=tCAN*SJW[1:0]+1)。
l        [22:20]TS2[2:0],时间段2
l        [19:16]TS1[1:0],时间段1.
l        [9:0]BRP[9:0],被波特率分频器。

先进入初始化模式,然后进行设置,最后退出初始化模式。
       CAN_Init(CAN1,&CAN_InitStructure);//使用结构体
       typedef struct
{
            uint16_t CAN_Prescaler;//设置分频系数
              uint8_t CAN_Mode;//模式设置
              uint8_t CAN_SJW;//设置重新同步跳跃宽度
              uint8_t CAN_BS1;//设置时间段1占用的时间单位
              uint8_t CAN_BS2;//设置时间段2占用的时间单位
              FunctionalState CAN_TTCM;//是否为时间触发通信模式
              FunctionalState CAN_ABOM;//是否为软件自动离线
              FunctionalState CAN_AWUM;//是否为睡眠模式通过软件唤醒
              FunctionalState CAN_NART;//是否开启报文自动传送
              FunctionalState CAN_RFLM;//是否锁定报文,锁定即新的不覆盖旧的
              FunctionalState CAN_TXFP;//优先级是否由报文标识符决定
       } CAN_InitTypeDef;
设置滤波器
      
CAN过滤器模式寄存器CAN_FM1R,位[13:0]FBMx,过滤器模式选择;0:过滤器组x232位寄存器工作在标识符屏蔽位模式;1:过滤器组x232位寄存器工作在标识符列表模式。
  CAN过滤器位宽寄存器CAN_FS1R,位[13:0]FSCx,过滤器位宽设置;0:过滤器位宽为216位;1:单个32位。
  CAN过滤器FIFO关联寄存器CAN_FFA1R,位[13:0]FFAx,过滤器关联设置,0:过滤器关联到FIFO01:关联到FIFO1.
  CAN过滤器激活寄存器CAN_FA1R
  CAN的过滤器组i的寄存器x CAN_FiRx,用来设置过滤器位。
进入初始化,然后设置,激活滤波器,最后退出初始化
       CAN_FilterInit();//使用结构体
       typedef struct
{
     uint16_t CAN_FilterIdHigh;//设置32ID高位

       uint16_t CAN_FilterIdLow;//设置32位ID低位

       uint16_t CAN_FilterMaskIdHigh;//设置32位mask id高位

       uint16_t CAN_FilterMaskIdLow;//设置32位mask id低位

       uint16_t CAN_FilterFIFOAssignment;//设置FIFO和过滤器的关联关系

       uint8_t CAN_FilterNumber;//设置初始化的过滤器组

       uint8_t CAN_FilterMode;//设置过滤器组的模式

       uint8_t CAN_FilterScale;//设置过滤器组的位宽

       FunctionalState CAN_FilterActivation;//是否激活过滤器

} CAN_FilterInitTypeDef;
至此CAN就可以开始工作了,初始化结束。
发送/接收消息
      
       CAN发送邮箱标识符寄存器CAN_TIxRx=0~2),
l        [31:21]STID[10:0]/EXID[28:0],标准标识符或扩展标识符。
l        [20:3]EXID[17:0],扩展标识符的低字节。
l        2IDE,标识符选择,标准还是扩展。
l        1RTR,远程发送请求。
l        0TXRQ,发送数据请求,软件置1,请求发送邮箱里的数据;数据发送完成时,邮箱为空,由硬件置0

CAN发送邮箱数据长度和时间戳寄存器CAN_TDTxR(X=0~2), [15:9]保留,位[7:4]保留。

l        [31:16]TIME[15:0],报文时间戳,在发送该报文SOF的时刻,16位定时器的值。
l        8TGT,发送时间戳,只有在CAN处于时间触发通信模式,该位才有效。
l        [3:0]DLC[3:0],发送数据长度。

CAN发送邮箱高/低字节数据寄存器CAN_TDLxR[x=0~2],该寄存器存储要发送的的数据,只存储4个字节,高低一共8个。

CAN_Transmit(CAN1,&TxMessage);//发送消息,使用结构体
       typedef struct
{
             uint32_t StdId;//设置标准标识符
              uint32_t ExtId;//设置扩展标识符
              uint8_t IDE;//标识符选择
              uint8_t RTR;//数据帧还是远程帧
              uint8_t DLC;//要发送的数据长度
              uint8_t Data[8];//发送的数据数组
       } CanTxMsg;

CAN接收FIFO邮箱标识符寄存器CAN_RIxRx=0/1),用来保存接收到的报文标识符等信息,通过读该寄存器来获取相关信息;各位描述与CAN_TIxR类似,只有0位保留。
CAN接收FIFO邮箱数据长度和时间戳寄存器CAN_RDTxRCAN接收FIFO邮箱高/低字节数据寄存器CAN_RDH/LxR

       CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//接收消息,使用结构体
       typedef struct
{
             uint32_t StdId;
              uint32_t ExtId;
              uint8_t IDE;
              uint8_t RTR;
              uint8_t DLC;
              uint8_t Data[8];
              uint8_t FMI;
       } CanRxMsg;
⑤  CAN状态获取
这里主要用到了以下几个:
        CAN_TransmitStaus();//消息的状态
        CAN_MessagePending();//是否接收到数据
        CAN_GetFlagStaus();//获取CAN位的状态
使用到的库函数文件是stm32f10x_can相关文件。
                                                                                                   11月6、7日

回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-7 22:22:01 来自手机 | 显示全部楼层
can的内容实在有些多。。。明天继续学习,就暂停一天
回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-9 19:01:38 | 显示全部楼层
第二十天红外遥控实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

红外遥控是一种无线、非控制技术,具有抗干扰能力强、传输信息可靠、功耗低、成本低、易实现等显著特点。
红外遥控的编码目前广泛使用的是:NEC Protocol PWM(脉冲宽度调制)Philips RC-5 Protocol PPM(脉冲位置调制)
NEC协议特征:
l       8位地址和8位指令长度;
l       地址和命令2次传输(确保可靠性)
l       PWM脉冲宽度调制,以发射红外载波的占空比代表“0”“1”
l       载波频率为38Khz
l       位时间为1.125ms2.25ms
NEC码位定义:
一个脉冲对应560us的连续载波,一个逻辑1传输需要2.25ms560us脉冲+1680us低电平),一个逻辑0的传输需要1.125ms560us脉冲+560us低电平)。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到的信号为:逻辑1应该是560us+1680us高,逻辑0应该是560us+560us高。
NEC遥控指令的数据格式为:
同步码头、地址码、地址反码、控制码、控制反码。同步码由一个9ms的低电平和一个4.5ms的高电平组成,地址码、地址反码、控制码、控制反码均是8位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可用于校验)。
此外,NEC码规定的连发码(9ms低电平+2.5m高电平+0.56ms低电平+97.94ms高电平组成),如果在一帧数据发送完毕之后,按键仍然没有放开,则发射重复码,即连发码,可以通过统计连发码的次数来标记按键按下的长短/次数。

程序设计思路:
l      开启定时器对应通道输入捕获功能,默认上升沿捕获。定时器的计数频率为1MHz,自动装载值为10000,也就是溢出时间我10ms
l      开启定时器输入捕获更新中断和捕获中断。当捕获到上升沿产生捕获中断,当定时器计数溢出,产生更新中断。
l      当捕获到上升沿的时候,设置捕获极性为下降沿捕获(为下次捕获下降沿做准备),然后设置定时器计数值为0(清空定时器),同时设置变量RmtSta的位4值为1,标记已经捕获到上升沿。
l      当捕获到下降沿的时候,读取定时器的值赋值给变量Dval,然后设置捕获极性为上升沿捕获(为下次捕获上升沿做准备),同时对变量RmtSta的位4进行判断:
      如果RmtSta41,说明之前已经捕获到过上升沿,那么对捕获值
      Dval进行判断,300-800之间,说明接收到的是数据0,1400-1800之间
      说明接收到的数据为1,2200-2600,说明是连发码,4200-4700说明为
      同步码。分析后甚至相应的标志位。
l      如果是定时器发生溢出中断,那么分析,如果之前接收到了同步码,并且是第一次溢出,标记完成一次按键信息采集。
l      RmtSta中保存的数据进行整理,判断地址码是否是自己希望得到的,判断地址码与地址反码是否相同;接收完数据之后,清除RmtSta的第6位,清除按键次数计数器(为下次按键做准备)。
119

回复 支持 反对

使用道具 举报

7

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2016-8-24
在线时间
62 小时
 楼主| 发表于 2016-11-9 21:04:47 | 显示全部楼层
DS18B20数字温度传感器实验。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
DS18B20为单总线,半双工通信方式。
DS18B20技术性能特征
l      独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。
l      测温范围 55℃~+125℃,精度为±05℃。
l      支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。
l      工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。
l      在使用中不需要任何外围元件。
l      测量结果以9~12位数字量方式串行传送。

DS18B20共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。

复位脉冲:单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时1560us,并进入接收模式(Rx)。应答信号:接着DS18B20拉低总线60~240 us以产生低电平应答脉冲。

  写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。
1时序:主机输出低电平,延时2us,然后释放总线,延时60us
0时序:主机输出低电平,延时60us,然后释放总线,延时2us
读时序:单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。
所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。
典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us

DS18B20的典型温度读取过程为:

复位☞SKIP ROM命令0XCC☞发开始转换命令0X44☞延时à复位☞发送SKIP ROM命令0XCC☞发读存储器命令0XBE☞连续读出两个字节数据(即温度)☞结束

                                                                                                                     119

回复 支持 反对

使用道具 举报

17

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
253
金钱
253
注册时间
2016-3-29
在线时间
96 小时
发表于 2016-11-9 21:16:21 | 显示全部楼层
本帖最后由 scx2006114 于 2016-11-9 21:19 编辑

给楼主提点小建议:1、多点创新,多自己组织语言去表达                           2、最后可以附上一些问题,让大家一起想想,一起讨论
                           3、重点标记的更清楚,更明了
回复 支持 反对

使用道具 举报

1

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2016-11-21
在线时间
43 小时
发表于 2016-11-22 00:13:59 | 显示全部楼层
支持楼主,毕竟追求一味实现功能并不能真正学懂  还得一步步来
回复 支持 反对

使用道具 举报

14

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
240
金钱
240
注册时间
2016-8-4
在线时间
71 小时
发表于 2016-11-22 00:55:11 来自手机 | 显示全部楼层
楼主厉害了,像我这刚看了一点就去做东西,然后好多配置都是移植,底层都不怎么看,一出错就各种懵逼,已开始像你一样把底层弄懂再做项目,谢谢楼主榜样
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 09:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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