如何使用TSL2301并在usart中制作时钟延迟

Posted

技术标签:

【中文标题】如何使用TSL2301并在usart中制作时钟延迟【英文标题】:How to use TSL2301 and make clock delay in usart 【发布时间】:2014-09-11 03:50:05 【问题描述】:

我正在研究一个名为 TSL2301 的线扫描 ccd 传感器。我想通过 stm32f103 的 USART 读取像素,但我总是只能收到 0xFF,有人使用这个传感器来帮助我吗? 我使用了STM32f10x的Usart同步模式,我通过Usart向传感器发送了一些命令,并希望在每个命令之后进行8个时钟延迟。我该怎么做?

int count=0;
int i=0;
uint8_t data[102]=0;
USART_ClockInitStructure.USART_Clock = USART_Clock_Enable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_High;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Enable;
USART_ClockInit(USARTy, &USART_ClockInitStructure);

USART_InitStructure.USART_BaudRate = 2200000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USARTy, &USART_InitStructure);

/* Configure the USARTy */
USART_Init(USARTy, &USART_InitStructure);

/* Enable the USARTy */
USART_Cmd(USARTy, ENABLE);

while(1)

while(count < 3)       
                                               
USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;

count=0;
USART_SendData(USARTy,0x1b);      //RESET command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);

USART_SendData(USARTy,0x1b);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);

USART_SendData(USARTy,0x1b);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);

USART_SendData(USARTy,0x08);  //StartInt Command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);

while(count < 20 )//DelayIntegrationTime() ;

USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;

count = 0;  
USART_SendData(USARTy,0x10);    //SampleInt Command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);

USART_SendData(USARTy,0x02);        //ReadPixel Command
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);

while(count < 2)

USART_SendData(USARTy,0xFF);
while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
count++;

count = 0;

 USART_Cmd(USARTy, DISABLE);
 USART_ClockInitStructure.USART_CPOL = USART_CPOL_High;
 USART_ClockInitStructure.USART_CPHA = USART_CPHA_1Edge;
 USART_ClockInit(USARTy, &USART_ClockInitStructure);
 USART_Init(USARTy, &USART_InitStructure);
 USART_Cmd(USARTy, ENABLE);

/*read pixels*/
for (i = 0; i < 102; i++) 

   while(USART_GetFlagStatus(USARTy, USART_FLAG_RXNE) == RESET);
   data[i] = USART_ReceiveData(USARTy);
   while(count < 1) 
   
   USART_SendData(USARTy,0xFF);
   while(USART_GetFlagStatus(USARTy, USART_FLAG_TC) == RESET);
   count++;
   
   count = 0;
 

 USART_Cmd(USARTy, DISABLE);
 USART_ClockInitStructure.USART_CPOL = USART_CPOL_High;
 USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
 USART_ClockInit(USARTy, &USART_ClockInitStructure);
 USART_Init(USARTy, &USART_InitStructure);
 USART_Cmd(USARTy, ENABLE);

【问题讨论】:

【参考方案1】:

STM32F103参考手册和TAOS datasheet中有不同的USART时序图。 我认为他们不会在 USART 模式下一起工作。

作为一个想法,您可以尝试使用 UART 而不是 USART。并使用 MCO 或其他时钟源为设备提供时钟。我认为它应该有效。

在这种情况下,您可以使用计时器进行所有延迟。

PS:但是还有一个问题你应该解决,就是同步UART的输出和时钟源。我需要更仔细地阅读 stm32 手册来告诉你如何去做。我稍后再做

【讨论】:

我有一个奇怪的解决方案给你。它应该在理论上有效,但我无法测试它。所以首先是硬件。您应该计算可以接受 UART 接收器的最大频率。应该是大约 1MBit/s。其次,您必须在此频率上配置定时器并为传感器制作时钟信号,并将其连接到 MCU 的 SPI clk 是的,您必须使用 SPI 发送同步数据 SPI MISO 引脚应连接到传感器串行输入 SPI 必须配置为从机并且有 16 位数据帧。您必须将 SPI 寄存器设置为 0xffff 才能使 IDLE USART 输出。当您需要发送数据时,您必须构建 1 个起始位,然后是数据,然后是停止位,这应该占用 10 位 SPI 数据寄存器,6 位保持设置为 1 也许很难理解。主要思想是仅使用UART来接收数据。和SPI发送数据。您也可以尝试使用 SPI 时钟输出并在主模式下运行 SPI。这将起作用,但您必须始终发送 FFFF 数据以生成时钟信号 希望这个cmets对你有用 我建议您首先在没有外部外围设备的情况下工作,仅使用较低频率的 GPIO。尝试从传感器接收一些信息。只有在那之后才能使用快速硬件移位寄存器。毕竟,您可以在 UART 和 SPI 上使用 DMA,并为其他任务腾出 CPU

以上是关于如何使用TSL2301并在usart中制作时钟延迟的主要内容,如果未能解决你的问题,请参考以下文章

如何制作一个永远运行的线程?

USART串口通信

USART串口通信

STM32 HAL USART驱动程序:此语法如何工作?

STM32 HAL USART 驱动程序:这种语法是如何工作的?

STM32串口USART1的使用方法