当前位置:首页 > 单片机 > 单片机
[导读]如果简单的使用USART的话配置相当简单,只要配置一下波特率,数据长度,停止位长度,校验位。然后再设置一下串口的引脚,输入为上后输入,输出为利用推挽输出。这样一来串口就配置好了,如果使用库则一目了然,如果使

如果简单的使用USART的话配置相当简单,只要配置一下波特率,数据长度,停止位长度,校验位。然后再设置一下串口的引脚,输入为上后输入,输出为利用推挽输出。这样一来串口就配置好了,如果使用库则一目了然,如果使用寄存器操作会繁琐一点找各个寄存器,因为设置波特率和设置数据长度等这些并不在一个寄存器中设置完成,还有可能忘记个别设置而无法找其原因。但寄存器操作的效率会很高。如下配置:

void USART_Initial(uint32_t Baud)

{

USART_InitTypeDef USART_InitStruct;

USART_GPIO(); //配置串口引脚

USART_InitStruct.USART_BaudRate=Baud; //波特率

USART_InitStruct.USART_WordLength=USART_WordLength_8b;//数据长度

USART_InitStruct.USART_StopBits=USART_StopBits_1;//停止位

USART_InitStruct.USART_Parity=USART_Parity_No;//奇偶校验

USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流失能

USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//使能接收和发送

USART_Init(USART1,&USART_InitStruct);

USART_Cmd(USART1,ENABLE);//打开串口

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开中断,本代码只在接收时用到

}

void USART_GPIO(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_SetBits(GPIOA,GPIO_Pin_9|GPIO_Pin_10);

}

我使能的USART1为PA9和PA10两个串口线。

如果使能到串口中断则在NVIC中设置好中断向量断并设置好优先级,并在串口寄存器中使能该中断。

void NVIC_USART_Initial(void)

{

NVIC_InitTypeDef NVIC_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;

NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;

NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStruct);

}

(中断优先级分组为2)

此时你可以在串口的中断服务代码中写入你想处理的代码。至于你想是接收中断还是发送中断或者传送错误中断还是奇偶校验,侦错误等中断你可以设置USART_ITConfig中设置,在void USART_Initial(uint32_t Baud)函数中最后一句第二个参数进行设置。

如果你想使能printf或者scanf来串口传输请看我的另一篇博文。http://blog.sina.com.cn/s/blog_79fbaced01011tpj.html

而串口的其它功能则没有用到,至于智能卡个人觉得应该挺有意思的,以后兴许会搞搞。而串口的同步模式不知道他和SPI比是不是速度更快,它的传输则由发送数据时产生CLK时钟和些时钟进行同步,接收数据也只有在此时才可以接收,也就是不可以独立的接收数据。

博主也试了串口DMA不中断是可以传输的,但是当我打开DMA传输完成中断时,发现串口没有数据,以为串口速度根不上DMA就提高了波特率发现还是不行。但当我使能DMA半传输中断时能够中断也能传输但是中断程序无法执行。。等高手回答。

下面则是ADC。因为实验仪上的ADC引脚引出来有限,所以很多功能未实现,首先就是ADCON这个东西一直有点混。一直以为使能此位这前校验ADC(手册上说校验ADC是ADCON=0必须在两个周期以上,但手册上又说ADCON=0时ADC消耗基本为0)后试过只有打开此位才可以校验。但是ADCON再次设置时可以启动ADC转换,手册上好像讲是启动规则转换,因为没有度过注入转换所以规则转换可以设置些位,也可以设置ADCx_CR2寄存器器中的外部触发来启动,规则通道则是先设置EXTSEL[2:0]位,如果设置成111即软件触发,后设置位20EXTTRIG位允许外部事件触发,最后设置位22SWSART来启动规则软件触发,而注入触发则同样设置CR2寄存器中的某些对应位来启动。

ADC有很多模式,而双ADC模式个人认为比较经典,或许见识有点少了。哈哈。这里不多说,为什么?没有经验,实验仪提供的资源多,但是随心的少。

SCAN模式,即扫描整个通道。如果规则通道组中有3个通道,则启动通道时转换完第一个自动转换第二个再然后第三个后停止并产生一个EOC事件,如果使能了中断则产生中断。(以前对中断头疼,现在觉得就是个纸老虎)

CONT即单词continue(本来看成count)当设置了SCAN又设置了CONT时将循环的转换通道,即上面转换完三后继续生第一个转换。同样的地方产生EOC。(应该是的,没有实践不敢断定)。

注入模式:一种是外部触发,优先于规则,如果有外部触发将打断正在转换的规则通道。直至完成。

自动注入模式:即转换完成规则通道后自动的切换到注入通道执行转换。

当然ADC还有很多,比如常常配合ADC的DMA。ADC时钟,外部触发的事件啊,等等细节。

配置ADC,这里不将时钟的打开,以上串口也未讲。

void ADC_Initial(void)

{

ADC_InitTypeDef ADC_InitStruct;

ADC_Cmd(ADC1,ENABLE); //启动ADC

System_Delay_us(100); //延时几个ADC周期

ADC_ResetCalibration(ADC1); //重置ADC校验

while(ADC_GetResetCalibrationStatus(ADC1)); //等待重置完成

ADC_StartCalibration(ADC1); //校验ADC

while(ADC_GetCalibrationStatus(ADC1)); //等待校验完成

ADC_InitStruct.ADC_Mode=ADC_Mode_Independent; //独立模式

ADC_InitStruct.ADC_ScanConvMode=DISABLE; //非扫描模式,当有多个ADC通道须要转换时可以使能此位

ADC_InitStruct.ADC_ContinuousConvMode=ENABLE; //连续转换使能

ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //外部触发条件,这里为软件触发

ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right; //右对齐模式

ADC_InitStruct.ADC_NbrOfChannel=1; //规则通道的个数,放在SQR寄存器的L[3:0]中

ADC_Init(ADC1,&ADC_InitStruct);

ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5); //开启通道10写入规则通道中,并设置第几个转换,转换周期为239

}

以上函数可以参考库手册。

再执行完ADC_Cmd(ADC1,ENABLE);这条语句就可以读通道10的AD转换值了。12位AD值在0~4096之间。然后将这些值打印到串口看其变化。你会发现变化波动还是较大的。可能极差并不会太大。你可以自己进行滤波。

昨天洗完澡回来后并无睡意,所以写了个滤波,但没什么新意,只是不厌其烦的取平均值。最后可以使AD值变化最大的情况下只有一个值的变化,一般情况下采样值都会是同一个值。但这样就大大(很大)牺牲了采样灵敏度。

不过这样的采样滤波不科学。有兴趣的同学可以上网搜下常见的AD的10大软件滤波程序。比较经典。

以下是一个简单的滤波代码。牺牲了速度。

#define GetValueTimes 30

#define DeleteValue 10

uint16_t ADC_GetValue(void)

{

uint8_t i,j;

uint16_t DigitalValue[GetValueTimes],SwapTreg;

uint32_t CalValue=0;

for(i=0;i

{

DigitalValue[i]=ADC_GetConversionValue(ADC1);

}

for(i=0;i

{

for(j=i+1;j

{

if(DigitalValue[i]>DigitalValue[j])

{

SwapTreg=DigitalValue[i];

DigitalValue[i]=DigitalValue[j];

DigitalValue[j]=SwapTreg;

}

}

}

for(i=DeleteValue,j=0;i

{

DigitalValue[j]=DigitalValue[i];

}

for(i=0;i

{

CalValue+=DigitalValue[i];

}

CalValue=CalValue/i;

return (uint16_t)CalValue;

}

#define SampleTimes 10

uint16_t MoveMix(void)

{

uint16_t SampleBuffer[SampleTimes];

uint8_t i,j;

uint32_t CalValue=0;

Lable: for(i=0;i

{

SampleBuffer[i]=ADC_GetValue();

}

for(i=0;i

{

for(j=i;j

{

if(abs(SampleBuffer[i]-SampleBuffer[j])>=20)goto Lable;

}

}

for(i=0;i

{

CalValue+=SampleBuffer[i];

}

CalValue/=i;

return (uint16_t)CalValue;

}

#define SampleTimes2 10

uint16_t MoreMix(void)

{

uint8_t i;

uint32_t CalValue=0;

for(i=0;i

{

CalValue+=MoveMix();

}

CalValue/=i;

return (uint16_t)CalValue;

}

#define SampleOver 5

uint16_t OverMix(void)

{

uint8_t i;

uint16_t OverValue[SampleOver];

Lable2: for(i=0;i

{

OverValue[i]=MoreMix();

}

for(i=0;i

{

if(OverValue[i]!=OverValue[i+1])goto Lable2;

}

return OverValue[0];

}


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在嵌入式开发中,STM32的时钟系统因其灵活性和复杂性成为开发者关注的焦点。然而,看似简单的时钟配置背后,隐藏着诸多易被忽视的陷阱,轻则导致系统不稳定,重则引发硬件损坏。本文从时钟源选择、PLL配置、总线时钟分配等关键环...

关键字: STM32 时钟系统

在嵌入式系统开发中,STM32系列微控制器的内部温度传感器因其低成本、高集成度特性,广泛应用于设备自检、环境监测等场景。然而,受芯片工艺差异和电源噪声影响,其原始数据存在±1.5℃的固有误差。本文从硬件配置、校准算法、软...

关键字: STM32 温度传感器

在能源效率与智能化需求双重驱动下,AC-DC转换器的数字控制技术正经历从传统模拟方案向全数字架构的深刻变革。基于STM32微控制器的PFM(脉冲频率调制)+PWM(脉冲宽度调制)混合调制策略,结合动态电压调整(Dynam...

关键字: AC-DC STM32

当前智能家居产品需求不断增长 ,在这一背景下 ,对现有浇花装置缺陷进行了改进 ,设计出基于STM32单片机的全 自动家用浇花机器人。该设计主要由机械结构和控制系统构成 ,机械结构通过麦克纳姆轮底盘与喷洒装置的结合实现机器...

关键字: STM32 麦克纳姆轮 安全可靠 通过性强

用c++编程似乎是让你的Arduino项目起步的障碍吗?您想要一种更直观的微控制器编程方式吗?那你需要了解一下Visuino!这个图形化编程平台将复杂电子项目的创建变成了拖动和连接块的简单任务。在本文中,我们将带您完成使...

关键字: Visuino Arduino ESP32 STM32

基于STM32与LoRa技术的无线传感网络凭借其低功耗、广覆盖、抗干扰等特性,成为环境监测、工业自动化等场景的核心解决方案。然而,如何在复杂电磁环境中实现高效休眠调度与动态信道优化,成为提升网络能效与可靠性的关键挑战。本...

关键字: STM32 LoRa

在实时控制系统、高速通信协议处理及高精度数据采集等对时间敏感的应用场景中,中断响应延迟的优化直接决定了系统的可靠性与性能上限。STM32系列微控制器凭借其灵活的嵌套向量中断控制器(NVIC)、多通道直接内存访问(DMA)...

关键字: STM32 DMA

数字电源技术向高功率密度、高效率与高动态响应方向加速演进,STM32微控制器凭借其基于DSP库的算法加速能力与对LLC谐振变换器的精准控制架构,成为优化电源动态性能的核心平台。相较于传统模拟控制或通用型数字控制器,STM...

关键字: STM32 数字电源

STM32微控制器凭借其针对电机控制场景的深度优化,成为高精度、高可靠性驱动系统的核心选择。相较于通用型MCU,STM32在电机控制领域的核心优势集中体现在FOC(磁场定向控制)算法的硬件加速引擎与PWM死区时间的动态补...

关键字: STM32 电机控制

无线充电技术加速渗透消费电子与汽车电子领域,基于Qi协议的无线充电发射端开发成为智能设备能量补给的核心课题。传统模拟控制方案存在响应滞后、参数调整困难等问题,而基于STM32的数字PID控制结合FOD(Foreign O...

关键字: STM32 无线充电
关闭