从STM32到TM4C123

发布者:咖啡狐狸最新更新时间:2020-11-25 来源: eefocus关键字:STM32  TM4C123  启动文件 手机看文章 扫描二维码
随时随地手机看文章

我主要是最近看ACfly的代码时,发现他有的工程的文件的.s文件讲道理是启动文件不是STM32,而是TM4C123,我怀疑是TI的芯片,查了下果然是的,应该是电赛准备的。但是这里可以看到换成其他芯片也是有专门的启动文件的。

 

 

 

 

从51单片机到STM32再到TM4C123

 

目录

系统时钟

GPIO相关

通用定时器相关

PWM相关

UART通信相关

 

写在前面:

进入TI的学习,说明STM32 已经掌握的差不多了,没有掌握的很好也没关系,正好两块单片机对比着学习更能加深映像。这篇只是简单的介绍TI,篇幅比较短比,主要还是叙述了32和TI的不同的地方,相似的就没有再写出来,不能完全的拿来当作学习资料。

 

一点学习TI的建议:

TI主要学习还是通过北航出版的《嵌入式系统教程——基于TivaC系列 ARM Cortex—M4微控制器》为主资料,因为这个资料比较通俗易懂,如果不喜欢看电子版的,可以去图书馆借这本书,还有一本配套的书,忘记叫啥名字了,但是想借的话直接图书馆检索TM4C123GH6PM就可以找到,这本书主要还是纯文字教你怎么配置相应功能和相应项目的思路。其次,除了北航的那本书,配套的资料还应该有《TM4C1233H6PM数据手册中文版》、中英文版本的《TM4CDriver_Library》,数据手册的话主要就是了解相关外设功能,以及对应映射引脚查找。《TM4CDriver_Library》主要是API文档,因为TI不同于32,TI的函数的入口参数无法通过像32一样的方法查找选择合适的参数,所以,该文档就很有作用,对于一个函数,可以通过该文档进行查找,找到函数所在的位置,有详细的关于该函数的讲解,可以了解该功能,同时还有入口参数的例子,若要选择其他入口参数,则复制该参数,在程序文件里面查找定义的位置,就可以看到附近还有同类的参数,选择需要的参数即可。


对于单片机的定时,那是一部分很重要的东西,这其中就有以分资料单独讲怎么配置各种定时器,实现不同功能,有例程,《TM4C123G定时器》就是一份资料,学习定时器的时候对照着来,会比较容易很多。


当然了,网上还有很多人的学习记录博客,这些也是很有用的资料,因为学习TI,就是要知道怎么用,怎么配置相关程序,博客就解决了这类问题。CSDN上面这一类型的TI教程不多,懒得找的话可以来找我拷贝。


系统时钟

对于51单片机来说,在书写程序时候是不需要进行系统的时钟函数的配置的,直接由晶振电路来提供。

 

如图所示,直接是32和TI的系统时钟框图

32系统时钟

TI系统时钟

 

对于32 的时钟来说,常用的时钟主要分为AHB和APB两大部分,且系统时钟不需要自己来配置。

/*

void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

*/

每个部分对应多大的频率,对应的定时器编号,串口编号也已经设定好。所以,在使用相对应的功能时候直接在这两类里面进行查找然后使能外设就可以用了,例如使用GPIO、定时器等功能时候直接用函数里面的参数来查找:
/*

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能 GPIOA 时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能串口

*/

 

然而,对于TI来说,系统的时钟也是分为AHB和APB两种,但是在配置时候可进行自由选择(由于初入TI,对这里没有仔细学习,感兴趣的可以了解),但是配置时钟时候,可以只需要运用“SysCtlClockSet()”函数来自己来设定,不像32一样直接规定了不同外设用不同的频率。函数的入口参数就是:系统的分频、使用OSC还是PLL、OSC时钟源选择、外接晶体频率,这四种来完成设备的时钟,例如:

/*

SysCtlClockSet ( SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ SYSCTL_OSC_MAIN )

*/

最后使能相应的功能即可。(关于其时钟配置的参数详细讲解见)。

在配置好系统的时钟之后,根据需要的外设功能进行相应的使能:

/*

SysCtlPeripheralEnable(uint32_t ui32Peripheral)

*/

其中的入口参数为 SYSCTL_PERIPH_GPIOA 、 SYSCTL_PERIPH_PWM1、 SYSCTL_PERIPH_TIMER1 等等。

注意:32的系统频率的配置是 固定的,定在了不同的总线的使能函数 ,所以不同的外设可以说是“不共用”系统时钟的,而TI是先于外设使能前进行自己 时钟 配置,然后才 使能 所需外设,且“公用”系统时钟。

GPIO相关

说完时钟和系统配置,下面简绍基本的GPIO口的配置。

 

GPIO的功能大致上还是和32的类似,可输出高低电平、UART通信、还可以模拟一些简单的通信接口,如SPI,IIC等。一般工作模式有以下几种:

浮空输入

上拉输入

下拉输入

模拟输入

开漏输出

推挽输出

复用推挽输出

复用开漏输出

 

一般GPIO在复位之后都有一个默认的方向,为了安全起见,都是默认为输入模式,废话不多说,直接进入配置:

首先是32的配置

/*

void LED_Init(void)

{

GPIO_InitTypeDef  GPIO_InitStructure;              

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);            

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                                      

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                           

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                           

GPIO_Init(GPIOB, &GPIO_InitStructure);                                                                     

GPIO_SetBits(GPIOB,GPIO_Pin_5);            

 

GPIO_Init(GPIOE, &GPIO_InitStructure);                                                                                                                                             

}

*/

其次是TI的配置:

/*

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);      //使能GPIOF外设         GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

*/

 

不难看出,配置32和TI的方式就是不一样的,32的GPIO是用结构体进行配置,TI则使用函数来进行配置。TI的普通配置只需要进行GPIO外设使能和方向控制即可。也不是说前面说到的功能模式就不能配置了,如果有需要可以进行其他类型的配置。

如果要进行端口高低电平的输出控制,32和TI也是一样的调用函数来进行配置,分别是:GPIO_SetBits(GPIOE,GPIO_Pin_5); 和 GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);

 

注意:TI的输出高低电平使用的是同一个函数GPIOPinWrite(),对于32则使用的是两个函数:GPIO_SetBits()和GPIO_ResetBit()即可输出高低电平。TI呢,则不是这样的,就连入口参数也不是和32一样那么简单,GPIOPinWrite()入口参数就有三个,分别是GPIO_PORTx_BASE,GPIO_PIN_x,和0(低电平时候为0,但是高电平时候不是1,而是GPIO_PIN_x)。例如PF1输出高电平 :

GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);

 

如果想进行其他端口详细的配置情况可以见相关手册资料,其中端口复用放在后面各功能实现时候讲。

通用定时器相关

TI定时器简介:

TI定时器呢,主要分为12个大的定时器模块(GPTM),每个定时器模块又分为定时器A和定时器B,所以总共有24个定时器。这12个大的定时器的属性分为16/32位的GPTM块和32/64位块,其中各6块。每个16/32位的定时器块,提供2路16位的定时器/计数器(即定时器A和定时器B),所以通俗来说就是定时器A或B单独配置时候就是12个16位的定时器,级联起来配置就是6个32位的定时器。同样的,32/64位的块就是12个32位的定时器,级联时候就变成6个64位的定时器。

功能说明:

每个 GPTM 模块的主要元件包括两个自由运行的递增/递减计数器(称作 Timer A 和 Timer B)、两个预分频器寄存器、两个匹配寄存器、两个预分频器匹配寄存器、两个影子寄存器、两个加载/初始化寄存器以及与它们相关的控制功能。

接着来,该单片机的定时器和32的有点不同,特别是计数控制计数的寄存器。配置了32的定时器之后,定时器开始计数,当计数达到重装载值时候产生中断,之后会重新“自动”装载计数值,但是Ti却并非如此,是否自动装载计数值是需要在配置时候进行设置的,官方一点的来说就是:单次触发 /周期定时器模式。

相关定时器的功能如下:

 

 

接着进入配置对比:

首先还是先32的配置:

/*

              TIM_TimeBaseStructure.TIM_Period = arr;

              TIM_TimeBaseStructure.TIM_Prescaler =psc;

              TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

              TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

              TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

*/

 

TI的配置:

/*

//TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);//单次计数模式

TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);//周期性计数模式

TimerLoadSet(TIMER0_BASE, 2222222- 1);//设定预装栽值

IntEnable(INT_TIMER0A);  //使能TIMER0A

TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); //TIMEOUT标志位触发中断

  //TIMER0A开始计数,当计数值等于TimerLoadSet,触发中断

*/

 

同GPIO口的配置一样的,32的配置还是结构体类型的配置,TI还是调用函数进行配置。

 

 

PWM模式:

通用定时器支持简单的PWM生成模式。在 PWM 模式中,定时器被配置为 24 位或 48 位递减计数器,也就是说在定时器里面就有这个功能,配置好以后就直接输出PWM,而不像32一样配置好定时器之后还要一个TIM_SetCompare1()函数来进行PWM的输出。

 

注意:除了前面介绍的不同点之后,与32还有一个很大的区别就是需要进行中断的执行相关功能时候,需要自己调用TimerIntRegister()函数来注册中断函数的名字,这样中断才有入口。如果不需要忽略即可。同时在使能中断时候,和32一样需要开启一些中断。

 

 

PWM相关

PWM简介:

TI有2个PWM模块,每个模块由4个PWM发生器模块和一个控制器模块组成,一共可以产生16个PWM输出。每个发生器模块都能够产生2个PWM信号,这两个信号是基于同一个定时器和频率,也可以配置成单独产生信号。PWM模块发生器产生的两个信号为PWMA和PWMB。

以下为结构图:

 

功能描述:

  • 时钟选择:系统时钟和预分频系统时钟

  • PWM定时器

每个PWM发生器中都有区别与通用定时器的定时器,在向下计数模式或向上/向下计数模式。

  • PWM比较器

每个PWM发生器都有两个比较器。具体功能和32一样就不再累赘。

  • PWM信号发生器

 

 

初始化及配置:

 

首先还是32的:

/*

              TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;

              TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

              TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

              TIM_OC2Init(TIM3, &TIM_OCInitStructure);

              TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

*/

 

其次是TI的:
/*

//单独配置的系统时钟

SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);

//配置引脚为PWM功能

syslPeripheralEnable(SYSCTL_PERIPH_GPIOF);

GPIOPinConfigure(GPIO_PF3_M1PWM7);

GPIOPinTypePWM(GPIOF, Pin3);

//配置 PWM1 Generator3·发生器

PMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN|PWM_GEN_MODE_NO_SYNC);

//配置 PWM1 Generator3 周期

PWenPeriodSet(PWM1_BASE, PWM_GEN_3, SysCtlClockGet()/freq - 1);

//配置 PWM1 Generator3·占空比

PMPulseWidthSet(PWM1_BASE, PWM_OUT_7, PWMGenPeriodGet(PWM1_BASE, PWM_GEN_3)*duty - 1);

//使能PWM1的输出

PWOutputState(PWM1_BASE, PWM_OUT_7_BIT, true);

//使能 PWM1 发生器模块

PMGenEnable(PWM1_BASE, PWM_GEN_3);

*/

 

还是和前面一样,32的PWM配置过程是结构体类型的,而TI则还是库函数来进行配置的。有一点值得注意哦,TI在配置PWM时候不需要进行IO口的复用配置和映射等相关操作,只要找到对应的IO口就可以输出信号。

 

UART通信相关

微控制器的UART简介:

TI控制器配备了多达8路的UART,其基本功能和32差不多,具体功能可以参考32相关文档

 

 

这部分我们先来看32和TI的配置,从配置中找不同的地方加以说明

 

首先是32配置:

/*

USART_InitStruct.USART_BaudRate=arr;

USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;

USART_InitStruct.USART_Parity=USART_Parity_No;

USART_InitStruct.USART_StopBits= USART_StopBits_1;

USART_InitStruct.USART_WordLength= USART_WordLength_8b;

USART_Init(USART2, &USART_InitStruct);

 

              USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

              USART_Cmd(USART2, ENABLE);

*/

32的配置过程就不加以叙述

 

TI的配置:

/*

    SCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);              //使能GPIO

              SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);//使能UART0

              GPIOPinConfigure(GPIO_PA0_U0RX); //复用GPIO

              GPIOPinConfigure(GPIO_PA1_U0TX);·

              GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);//

[1] [2]
关键字:STM32  TM4C123  启动文件 引用地址:从STM32到TM4C123

上一篇:STM32程序的烧录方式 与 ISP一键下载
下一篇:STM32之中断与事件---中断与事件的区别

推荐阅读最新更新时间:2024-11-07 16:31

基于STM32的单通道示波器制作成功
终于把基于STM32的示波器做出来啦!本来想用外部高速AD做一个1Mhz采样率的示波器,由于自己没有制作示波器经验,手头上也没现成的IC,于是就先利用STM32内部的12位AD做了一个简易示波器,小练一下示波器的制作,以后有时间再继续做一个实用性较强的便携式示波器吧。 该示波器的硬件配置为:3.7V锂电池供电,显示屏为带触摸的16位3.2寸TFT液晶,主控芯片为STM32F103VC。为了省事,信号触发采用软件触发,幅值、周期、XY轴偏移都是通过触控屏来设置。(由于宿舍没有函数发生器,下面演示图片中的波形是由LM358搭出来的简易信号发生器,波形非常不规则) 下为示波器的实物图(后面那块小小的东西为简陋的波形发生器):
[测试测量]
基于<font color='red'>STM32</font>的单通道示波器制作成功
独立看门狗实狗实验—IWDG
概述: 为什么要看门狗? 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog) 。 独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它仍有效。 独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。 功能介绍: 在键值寄存器(IWDG_KR)中写入0xCCCC,开始
[单片机]
独立看门狗实狗实验—IWDG
STM32存储器理解
分类: 1 ROM (EPROM、EEPROM、NOR_Flash、NAND_Flash) 只读存储器,断电后数据保存,以前ROM是只能读取,不能擦写的,随着技术的发展,flash逐渐取代了rom,但功能上还沿用了rom的作用,所以把它归为rom类。 2 RAM (SRAM) 随机存储器,掉电数据丢失,但它的最大有点就是读写速度快,典型的RAM就是内存条。 加深理解: 在KEIL5中点击魔术棒,再点击TARGET,在下面的选型中有如下选项: options for target ROM 外部只读存储器 用户设置 RAM 外部随机存储器 用户设置 IROM
[单片机]
<font color='red'>STM32</font>存储器理解
【STM库应用】stm32 之 IIC应用
iic协议是比较简单的双线协议,时钟线CLK和数据线SDA。 一般我们常见的还有spi总线,这种总线可以可以根据需要扩展,还有单总线等等 这次还以at240c2为例进行操作! PS:这就是传说中的iic时序图 硬件构造我们不过多的分析,今天用到库了!我们先从库函数硬件iic初始化说起! PB6 -- CLK PB7 -- SDA void i2c_init(u8 addr,u32 clock) { I2C_InitTypeDef i2c; RCC- APB2ENR |= 1 3; GPIOB- CRL |= (u32)0xff (6*4); RCC_APB1PeriphClockCm
[单片机]
【STM库应用】<font color='red'>stm32</font> 之 IIC应用
STM32的备份电池寿命
请教诸位使用STM32的兄弟: 如果用50mah的备份电池给STM32的RTC供电,能坚持多长时间?规格书上IDD_VBAT是。而VBAT的范围是1.8~3.6V。 ST是否有相应针对特定电池的数据。 -------------------------------------------------------------------- 半导体公司不会给出一个准确的数据,一般自己计算一下就好了。 比如50mAh的电池按照1.4uA放电,可以使用的时间为:50mAh / 1.4uA = 35714小时 CR2025电池 电压3.0V,容量150,尺寸20.0X2.5mm, 重量2.4g 150mAh / 1.4uA =
[单片机]
STM32串口1,2,3初始化函数代码(标准库版)
没有使用中断 cks32C8T6、stm32c8t6直接复制使用 其他芯片注意引脚,复用功能什么的 串口1初始化代码 //串口1 void Uart1_init(u32 bound){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 //USART1_TX GPIOA.9 GPIO_InitStruc
[单片机]
基于STM32的红外遥控重点解析
本文有两个内容:一、红外遥控协议的的讲解;二、解码程序解析(参考正点原子的代码) 红外的介绍、优点、缺点就不给大家说了,进入正题 一、红外遥控协议的的讲解 红外遥控的编码目前广泛使用的是:NEC Protocol的PWM(脉冲宽度调制)和Philips RC-5 Protocol的PPM(脉冲位置调制) 本文将以NEC协议实现红外遥控。 NEC协议的特征: 1、8位地址和8位指令长度; 2、地址和命令两次传输;(确保可靠性) 3、PWM脉冲宽度调制,以发射红外载波的占空比代表“0”和“1”; 4、载波频率为38KHz 5、位时间为1.125ms和2.25ms NEC码位的定义:一个脉冲对应560us的连续载波,一个逻辑1传输需要2
[单片机]
基于<font color='red'>STM32</font>的红外遥控重点解析
STM32_管脚 部分映射和全映射
在管脚映射的时候一定要记得开启映射的时钟RCC_APB2Periph_AFIO 如下 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_PD01, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);//全部释放 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); 映射了PD0,
[单片机]
STM32_管脚 部分映射和全映射
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved