Other Parts Discussed in Thread: TM4C123GH6PM
您好!
我有一位客户需要流程图、就像 TM4C123GH6PM 数据表中的第1010页一样、了解如何对寄存器算法进行编码。
客户已经使用 RTVA TM4C123GH6PM 为 GPIO、SPI、i2c 和 uasrt 创建了自己的库、但他需要数据表第1010页中的说明或流程图、以便对 ADC、计时器等进行编码
我希望您能帮助我们的客户回答他的问题。 非常感谢。
此致、
Ray Vincent
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Other Parts Discussed in Thread: TM4C123GH6PM
您好!
我有一位客户需要流程图、就像 TM4C123GH6PM 数据表中的第1010页一样、了解如何对寄存器算法进行编码。
客户已经使用 RTVA TM4C123GH6PM 为 GPIO、SPI、i2c 和 uasrt 创建了自己的库、但他需要数据表第1010页中的说明或流程图、以便对 ADC、计时器等进行编码
我希望您能帮助我们的客户回答他的问题。 非常感谢。
此致、
Ray Vincent
尊敬的 Ray:
其他模块没有此类流程图。 我可以理解这种流程图、这可能对 I2C 模块特别有用、如第1010页所示、因为步骤序列对于 I2C 正常工作非常重要。 即使对于 I2C、TivaWare API 也会将用户流程图抽象化。 我认为其他模块不需要此类流程图。 对于计时器和 ADC、只需配置一些控制寄存器、然后启用模块即可。 对于必须首先对哪个控制寄存器进行编程以及哪个控制寄存器是第二个和第三个等、没有实际要求。 通常、最后一步是启用模块。 您可以让客户参考 TivaWare ADC 和计时器示例以供参考。
您好、Charles、
你好。 请参阅下面我们客户的回复。 谢谢。
您好!
我不太理解您的客户在寻求什么帮助。 问题是否特定于 SysTick 模块? 在 SysTick 处理程序中、他尝试禁用 SysTick 模块。 我认为没有必要这样做。 SysTick 是一个计时器模块、它定期生成中断。 在中断中、需要完成的工作全部由应用程序来完成。 他可以通过 SCB->ICSR|=1<<25来清除中断位。
对于其他模块、在中断 ISR 中、应用程序通常会找出导致中断的原因、然后清除中断状态标志。 在 TivaWare 中、您将调用 xxxIntStatus()来找出导致中断的原因、然后调用 xxxIntClear ()来清除中断标志。 例如,您将调用 TimerIntStatus()以找出导致计时器中断的原因(例如匹配、超时等),然后调用 TimerIntClear ()以清除中断标志。
同样、我不明白为什么您的客户想要构建自己的驱动程序、而这种驱动程序已经过验证且易于使用、可以随时使用并得到我们的支持。 我们无法支持自定义驱动程序。
尊敬的 Ray:
很抱歉、我真的不知道如何在这里为您提供帮助。 正如我在第一次答复中所提到的、没有流程图说明要为每个外设设置和清除哪些寄存器。 不过、数据表说明中介绍了如何初始化外设。 您只需转到相应的外设即可查看说明。 例如、在数据表中、对于 SPI 模块、您将在下面找到有关如何配置寄存器的说明。 但愿这对您有所帮助。 如果这不是您想要的、那么我们真的希望您只关注 TivaWare 外设驱动程序和 TivaWare 库中的各种示例。
15.4初始化和配置
要启用和初始化 SSI、需要执行以下步骤:
1、通过 RCGCSSI 寄存器(见第346页)使能 SSI 模块。
2.通过 RCGCGPIO 寄存器(见340页)使能相应 GPIO 模块的时钟。
要了解哪个 GPIO 端口可以使能、请参考第1351页的表23-5。
3.将相应管脚的 AFSEL 位置位(见671页)。 以确定要使用哪些 GPIO
请参阅第1344页的表23-4。
配置 GPIOPCTL 寄存器的 PMCn 域、将 SSI 信号赋给相应的管脚
引脚。 见第688页和第1351页的表23-5。
5、对 GPIODEN 寄存器进行编程、使能管脚的数字功能。 此外、驱动强度
必须配置漏极选择和上拉/下拉功能。 请参阅“通用”
输入/输出(GPIO)”。
注意:上拉电阻可用于避免 SSI 引脚上不必要的切换、而这种切换可采用
从器件进入错误状态。 此外、如果 SSIClk 信号被编程为稳定状态
通过 SSICR0寄存器的 SPO 位设置为高电平、则软件也必须配置
与 SSInClk 信号相对应的 GPIO 端口引脚、作为 GPIO 上拉电阻中的上拉电阻
选择(GPIOPUR)寄存器。
对于每种帧格式、SSI 均按照以下步骤进行配置:
在对配置进行任何更改之前、应确保 SSICR1寄存器的 SSE 位清零。
2.选择 SSI 是主机还是从机:
a:对于主机操作、将 SSICR1寄存器设置为0x0000.0000。
b.对于从机模式(输出使能)、将 SSICR1寄存器设置为0x0000.0004。
c.对于从机模式(输出被禁用)、将 SSICR1寄存器设置为0x0000.000C。
3.通过写 SSICC 寄存器来配置 SSI 时钟源。
4、通过写 SSICPSR 寄存器配置时钟预分频除数。
5.向 SSICR0寄存器写入以下配置:
■μ s 串行时钟速率(SCR)
如果使用飞思卡尔 SPI 模式(SPH 和 SPO)、则需要■μ s 的时钟相位/极性
■协议模式:Freescale SPI、TI SSF、MICROWIRE (FRF)
■数据大小(DSS)
6.可选择将 SSI 模块配置为 μ μDMA 使用、步骤如下:
a.配置 μ μDMA 供 SSI 使用。 请参阅第585页上的“微型直接存储器存取(μDMA)”
更多信息。
b.将中的 TXDMAE 或 RXDMAE 位置位、使能 SSI 模块的 TX FIFO 或 RX FIFO
SSIDMACTL 寄存器。
将 SSICR1寄存器的 SSE 位置位、使能 SSI 模块。
例如、假设 SSI 必须配置为使用以下参数运行:
μ■主器件操作
■飞思卡尔 SPI 模式(SPO = 1、SPH = 1)
■1Mbps 比特率
■8个数据位
假设系统时钟为20MHz、则位速率计算为:
SSInClk = SYSCLK /(CPSDVSR *(1 + SCR))
1x106 = 20x106/(CPSDVSR *(1 + SCR))
在这 种情况下、如果 CPSDVSR=0x2、SCR 必须为0x9。
配置顺序如下:
1.确保 SSICR1寄存器的 SSE 位清零。
2.向 SSICR1寄存器写入0x0000.0000。
3.向 SSICPSR 寄存器写入0x0000.0002。
4.向 SSICR0寄存器写入0x0000.09C7。
将 SSICR1寄存器的 SSE 位置位、使能 SSI 模块。
您好、Charles、
你好。 请参阅以下客户对您建议的回应。 谢谢。
好的、我知道数据表如何初始化外设我打印数据表并阅读它。 我想我们处于闭环中。 正如我一开始提到的。 我知道如何启用外设。 当您阅读数据表时、您可以向我展示如何读取 UART 外设或 SPI 外设等 你不能告诉我。 我向您发送了一个闭环 UART 发送数据 C 函数。
您能否向我展示数据表中除初始化章节外的外设读取、写入操作示例?
您可能不会显示、因为我阅读了所有数据表、但我找不到它。
此致、
Ray Vincent
UART 发送数据 C 的功能是什么? 您是在何时发送的? 在 您之前的任何回复中、我没有看到任何 UART C 函数? 我想我们有一个沟通问题。 我并不真正理解 您 对"闭环"的含义。
UART 上有 TivaWare 示例。 如果您想了解 UART 的工作原理、请查看示例并查看 API 的源代码如何使用寄存器。
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
//*****************************************************************************
//
//! \addtogroup example_list
//! <h1>UART Echo (uart_echo)</h1>
//!
//! This example application utilizes the UART to echo text. The first UART
//! (connected to the USB debug virtual serial port on the evaluation board)
//! will be configured in 115,200 baud, 8-n-1 mode. All characters received on
//! the UART are transmitted back to the UART.
//
//*****************************************************************************
//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************
void
UARTIntHandler(void)
{
uint32_t ui32Status;
//
// Get the interrrupt status.
//
ui32Status = ROM_UARTIntStatus(UART0_BASE, true);
//
// Clear the asserted interrupts.
//
ROM_UARTIntClear(UART0_BASE, ui32Status);
//
// Loop while there are characters in the receive FIFO.
//
while(ROM_UARTCharsAvail(UART0_BASE))
{
//
// Read the next character from the UART and write it back to the UART.
//
ROM_UARTCharPutNonBlocking(UART0_BASE,
ROM_UARTCharGetNonBlocking(UART0_BASE));
//
// Blink the LED to show a character transfer is occuring.
//
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
//
// Delay for 1 millisecond. Each SysCtlDelay is about 3 clocks.
//
SysCtlDelay(SysCtlClockGet() / (1000 * 3));
//
// Turn off the LED
//
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
}
}
//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void
UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
{
//
// Loop while there are more characters to send.
//
while(ui32Count--)
{
//
// Write the next character to the UART.
//
ROM_UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++);
}
}
//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int
main(void)
{
//
// Enable lazy stacking for interrupt handlers. This allows floating-point
// instructions to be used within interrupt handlers, but at the expense of
// extra stack usage.
//
ROM_FPUEnable();
ROM_FPULazyStackingEnable();
//
// Set the clocking to run directly from the crystal.
//
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
//
// Enable the GPIO port that is used for the on-board LED.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//
// Enable the GPIO pins for the LED (PF2).
//
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
//
// Enable the peripherals used by this example.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable processor interrupts.
//
ROM_IntMasterEnable();
//
// Set GPIO A0 and A1 as UART pins.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Configure the UART for 115,200, 8-N-1 operation.
//
UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
//
// Enable the UART interrupt.
//
ROM_IntEnable(INT_UART0);
ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
//
// Prompt for text to be entered.
//
UARTSend((uint8_t *)"\033[2JEnter text: ", 16);
//
// Loop forever echoing data through the UART.
//
while(1)
{
}
}
您好、Charles、
抱歉、我以为我会向您发送客户提供的闭环 UART 发送数据 C 函数。 由于不允许在 E2E 中发布客户电子邮件地址、因此我只分享我们在我们这边讨论的内容。 请多多包涵、但我愿意为您和客户提供支持、以便我们能够帮助客户提出问题。 下面是闭环 UART 发送数据 C 函数。 非常感谢您的支持。 尽管这是一个艰难的过程、但我非常感谢您的帮助。
闭环 UART 发送数据函数的另一个示例。
1)首先我检查了数据长度
2)第二个 FIFO 已满
3) 3)最后一次检查是 FIFO 空。
对于每个外设、我们都必须检查一些寄存器、如您所见。我只要求您提供具有特殊属性的处理器的指导行或流程图。
void UART_recive_Data (USART_Handle_t * pUART_Handle、uint8_t * pRxBuffer、uint32_t Len){
while (len>0)
{
while (UART_Flag_Status (pUART_Handle、recive_FIFO_Full)=0)
{}
*pRxBuffer|=pUART_Handle->pUSARTx->DR;
pRxBuffer++;
len-;
while (UART_Flag_Status (pUART_Handle、recive_FIFO_EMPTY)!= 0){}
}
}
此致、
Ray Vincent
尊敬的 Ray:
为什么要等待 FIFO_FULL 标志设置为按以下行继续? 假设您的 Len=5、但 FIFO 未满、因此您只需等待即可。 如果发送器没有向您发送任何更多数据、那么您只需在此行中等待、因为 FIFO 尚未满。
while (UART_Flag_Status (pUART_Handle、recive_FIFO_Full)=0)
{}
我建议您只检查 FIFO_EMPTY 标志。 如果 FIFO 不为空、则继续从 FIFO 读取数据、直到到达 Len 或 FIFO 变为空。 正如我提到过的、您可以参考 TivaWare 示例。 在此 UART_echo 示例中、UARTIntHandler ISR 会在接收 FIFO 中存在字符时循环。 它一直读取 FIFO、然后发送接收到的数据、直到 FIFO 变空。
void
UARTIntHandler(void)
{
uint32_t ui32Status;
//
// Get the interrrupt status.
//
ui32Status = MAP_UARTIntStatus(UART0_BASE, true);
//
// Clear the asserted interrupts.
//
MAP_UARTIntClear(UART0_BASE, ui32Status);
//
// Loop while there are characters in the receive FIFO.
//
while(UARTCharsAvail(UART0_BASE))
{
//
// Read the next character from the UART and write it back to the UART.
//
UARTCharPutNonBlocking(UART0_BASE,
MAP_UARTCharGetNonBlocking(UART0_BASE));
}
}