keil4調試sp3485(非中斷)

1.原因

課題需要通過stm32 usart3驅動485協議。

2.硬件

RE和DE都下拉,PA08是sp3485的發送/接收使能端,sp3485只能支持半雙工的通信,這個引腳就是來控制這個芯片到底是收數據還是發數據。這個電路有以下幾個問題:

(1)A B 沒做上下拉,那麼如果A B線空閒的情況下,線上電壓在SP3485門限電壓-200mv~200mv之間,邏輯電平不確定,可能導致總線上出現莫名的數據。 (2)A B線之間沒有TVS,防止總線浪湧,在浪湧出現的情況下,可能導致芯片損壞。 (3)另外,如果環境複雜,還要考慮二次的防雷擊浪湧保護以及電源隔離,放置地平面環流。

3.sp3485

來源:周立功sp345

4.程序

初始化程序

void ConfigurationUsart3(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	/* config USART3,PA.8 clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

	/* USART3 GPIO config */
   /* Configure USART3 Tx (PB.10) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	    
    /* Configure USART3 Rx (PB.11) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	  
	/* USART3 mode config */
	USART_InitStructure.USART_BaudRate = 115200;
	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(USART3, &USART_InitStructure); 
    USART_Cmd(USART3, ENABLE);

	/*USART3 Direction Config PA.8*/
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIOA->ODR &= ~GPIO_Pin_8;           //拉低電平接受使能
}

主程序


int main(void)
{	   
        int i=3; 
        SystemInit();
	
	   	ConfigurationUsart3(); 
while(i--)
	    {
          GPIOA->ODR |= GPIO_Pin_8;  //拉高電平 發送使能
		USART3_printf( USART3, "This is a usart3_printf demo \r\n " );  
        Command_Delay(200);   //等待發送完成
	    GPIOA->ODR &= ~GPIO_Pin_8;   // 拉低電平,等待接受
   
	 	}

}

發送打印程序

/*
 * 函數名:itoa			   指針函數
 * 描述  :將整形數據轉換成字符串
 * 輸入  :-radix =10 表示10進制,其他結果爲0
 *         -value 要轉換的整形數
 *         -buf 轉換後的字符串
 *         -radix = 10
 * 輸出  :無
 * 返回  :無
 * 調用  :被USART3_printf()調用
 */
static char *itoa(int value, char *string, int radix)
{
    int     i, d;
    int     flag = 0;
    char    *ptr = string;

    /* This implementation only works for decimal numbers. */
    if (radix != 10)
    {
        *ptr = 0;
        return string;
    }

    if (!value)
    {
        *ptr++ = 0x30;
        *ptr = 0;
        return string;
    }

    /* if this is a negative value insert the minus sign. */
    if (value < 0)
    {
        *ptr++ = '-';

        /* Make the value positive. */
        value *= -1;
    }

    for (i = 10000; i > 0; i /= 10)
    {
        d = value / i;

        if (d || flag)
        {
            *ptr++ = (char)(d + 0x30);
            value -= (d * i);
            flag = 1;
        }
    }

    /* Null terminate the string. */
    *ptr = 0;

    return string;

} /* NCL_Itoa */

/*
 * 函數名:USART_printf
 * 描述  :格式化輸出,類似於C庫中的printf,但這裏沒有用到C庫
 * 輸入  :-USARTx 串口通道,這裏只用到了串口2,即USART2
 *		     -Data   要發送到串口的內容的指針
 *			   -...    其他參數
 * 輸出  :無
 * 返回  :無 
 * 調用  :外部調用
 *         典型應用USART3_printf( USART2, "\r\n this is a demo \r\n" );
 *            		 USART3_printf( USART2, "\r\n %d \r\n", i );
 *            		 USART3_printf( USART2, "\r\n %s \r\n", j );
 */
void USART3_printf(USART_TypeDef* USARTx, uint8_t *Data,...)
{
	const char *s;
  int d;   
  char buf[16];

  va_list ap;
  va_start(ap, Data);

	while ( *Data != 0)     // 判斷是否到達字符串結束符
	{				                          
		if ( *Data == 0x5c )  //'\'
		{									  
			switch ( *++Data )
			{
				case 'r':							          //回車符
					USART_SendData(USARTx, 0x0d);
					Data ++;
					break;

				case 'n':							          //換行符
					USART_SendData(USARTx, 0x0a);	
					Data ++;
					break;
				
				default:
					Data ++;
				    break;
			}			 
		}
		else if ( *Data == '%')
		{									  //
			switch ( *++Data )
			{				
				case 's':										  //字符串
					s = va_arg(ap, const char *);
          for ( ; *s; s++) 
					{
						USART_SendData(USARTx,*s);
						while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
          }
					Data++;
          break;

        case 'd':										//十進制
          d = va_arg(ap, int);
          itoa(d, buf, 10);
          for (s = buf; *s; s++) 
					{
						USART_SendData(USARTx,*s);
						while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
          }
					Data++;
          break;
				 default:
						Data++;
				    break;
			}		 
		} /* end of else if */
		else USART_SendData(USARTx, *Data++);
		while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
	}
}

5、完整程序代碼

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章