stm32f4 프로세서를 이용해서 VCP 환경만들기


USB를 사용하기 때문에 케이블과 시리얼 포트가 필요없다. 때문에 앞으로 많이 사용 할 것 같다.

먼저 VCP를 사용하기 위해서는 드라이버가 필요하다.


http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-utilities/stsw-stm32102.html


다운로드를 받고 설치를 하면 

VCP 포트가 활성화 된다.



https://github.com/mfauzi/STM32F4/tree/master/STM32F4%20Discovery%20Software%20Examples/STM32F4xx_USB_Example  << stm32f4 vcp 라이브러리


usbd_cdc_vcp.c 의  VCP_DataTx 를 수정해야한다. 이것 때문에 좀 고생했다.

uint16_t VCP_DataTx(uint8_t *Buf, uint32_t Len)

{

    uint32_t i;


    // Put the data into the buffer. It will be processed by the USB stack.

    for (i=0; i<Len; i++)

    {

        // Add a byte to the buffer

        APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i];


        // Update the circular buffer index

        APP_Rx_ptr_in++;


        // Loop the index if necessary

        if (APP_Rx_ptr_in == APP_RX_DATA_SIZE)

        {

            APP_Rx_ptr_in = 0;

        }

    }

    return USBD_OK;

}




 

uint8_t Buf[6] = "ABCDE";

VCP_DataTx(Buf, 6);




stm32f4 에 vcp 라이브러리 소스를 다운로드 받고 

ABCDE 를 PC에 전송한다.






PC에 정상적으로 전송되었다. 이로써 시리얼 케이블과 변환기를 연결하는 번거러움 없이 pc에 시리얼 데이터를 보낼 수 있게 되었다. 





'공부 > stm32' 카테고리의 다른 글

can통신 신호 분석  (1) 2016.07.27
stm32f4 can 통신 무작정  (2) 2016.07.25
stm32f4 클럭상태 출력하기  (0) 2016.07.25

다이오드 타버림



파워 다이오드가 날라갔지만  stm32f4 칩은 무사했다




굴러다니는 다이오드 장착 

다행이 st link도 잘 작동함.





can 통신을 할 때 통신 속도를 맞춰주어야 하는데, bitrate를 맞추기 위해서 디스커버리 칩의 클럭을 알맞은 값 을 설정해 주어야 한다. 디스커버리 보드에서 can1 은 APB1 클럭에 영향을 받는다. 먼저 APB1을 42MHz로 세팅한다.






STM32CubeMX 프로그램을 이용하여 원하는 클럭을 만들어 낼 수 있다.







/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      4
#define PLL_N      168
 
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2
 
/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      7
 
/******************************************************************************/
cs
PLL을 수정하여 APB1 42MHz 세팅





CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CANInitStructure.CAN_BS1 = CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;
CAN_InitStructure.CAN_Prescaler = 840;


cs


BS와 프리스케일러를 수정하여 can통신 bitrate를 10Kbs로 설정






data[0= 0x01; data[1= 0xFF; data[2= 0xFF; data[3= 0xFF; data[4= 5; data[5= 6; data[6= 7; data[7= 8;
Can_TxMessage(0x0141, data);
cs


0x014 의 식별자로 1바이트의 데이터 date[0]을 보냈다.






값 을 받아낸다. 이제 오실로스코프로 찍어본다.






can 통신은 can_H선과 can_L선의 전압차이를 이용해서 데이터 통신을 한다. 위 사진은 can_H선과 can_L선의 파형을 오실로스코프에 나타낸 것이다. 아래 파형은 can_H can_L선 사이의 전압차이를 반전시킨 파형이다. 결국 아래파형이 통신 데이터 파형이다.





can 트랜시버에서 나온 데이터 파형







'공부 > stm32' 카테고리의 다른 글

stm32f4 VCP(virtual com port)  (0) 2016.08.30
stm32f4 can 통신 무작정  (2) 2016.07.25
stm32f4 클럭상태 출력하기  (0) 2016.07.25

 discovery 보드로 통신



http://blog.naver.com/solsol8711/188508351


쏠쏘리님 네이버 블로그 에서 많은 도움 받음



can통신을 하게될 디스커버리보드 2개






can통신을 하기위해서는 can트랜시버가 필요하다. Atmel ATA6660 IC를 사용






선을 연결하고




잘 나옴


아래는 소스 

개발환경은 IAR 

STM32F4 DISCOVRY



#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
 
#include <stdio.h>
 
 
#ifdef __GNUC__
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
 
/*
static void delay(volatile unsigned int number)
{
    for(; number>0; number--);
}
*/
 
PUTCHAR_PROTOTYPE
{
    /* Write a character to the USART */  
    if( ch == '\n') {
        USART_SendData(USART1, '\r');
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        USART_SendData(USART1, '\n');
    }else {
        USART_SendData(USART1, (u8) ch);
    }
    /* Loop until the end of transmission */
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 
    return ch;
}
 
 
 
void USART1_Configuration(void)
{
 
    /* USART1 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    /* GPIOB clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    
    
    GPIO_InitTypeDef GPIO_InitStructure;
    /*-------------------------- GPIO Configuration ----------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    /* Connect USART pins to AF */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // USART1_TX
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // USART1_RX
    
    
    USART_InitTypeDef USART_InitStructure;
    /* USARTx configuration ------------------------------------------------------*/
    /* USARTx configured as follow:
        - BaudRate = 115200 baud
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
    */
    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(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
}
 
 
#include "drv_can.h"
 
SCan sCan[CAN_MAX_ID];
CanRxMsg RxMessage0;
CanTxMsg TxMessage;
 
void Can_Init()
{
    GPIO_InitTypeDef         GPIO_InitStructure;
      CAN_InitTypeDef            CAN_InitStructure;
      NVIC_InitTypeDef         NVIC_InitStructure;
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 
      GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_CAN1);
      GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_CAN1); 
  
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
 
      CAN_DeInit(CAN1);
 
      CAN_InitStructure.CAN_TTCM = DISABLE;
      CAN_InitStructure.CAN_ABOM = DISABLE;
      CAN_InitStructure.CAN_AWUM = DISABLE;
      CAN_InitStructure.CAN_NART = DISABLE;
      CAN_InitStructure.CAN_RFLM = DISABLE;
      CAN_InitStructure.CAN_TXFP = ENABLE;
      CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
 
    
      CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
      CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
      CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
      CAN_InitStructure.CAN_Prescaler = 60;
    
      CAN_Init(CAN1, &CAN_InitStructure);
 
       CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
      
      NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
}
 
/*
filterMode = CAN_FilterMode_IdMask, CAN_FilterMode_IdList
FiltNum = 0~13
*/
void Can_FilterConfig(uint8_t filterMode, uint8_t FiltNum, uint16_t IDHigh, uint16_t IDLow, uint16_t MaskHigh, uint16_t MaskLow)
{
    CAN_FilterInitTypeDef      CAN_FilterInitStructure;
      CAN_FilterInitStructure.CAN_FilterNumber = FiltNum;
      CAN_FilterInitStructure.CAN_FilterMode = filterMode;
      CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
      CAN_FilterInitStructure.CAN_FilterIdHigh = IDHigh << 5;
      CAN_FilterInitStructure.CAN_FilterIdLow = IDLow<<5;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh = MaskHigh;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow = MaskLow;
      CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
      CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
      CAN_FilterInit(&CAN_FilterInitStructure);
}
 
/*
index = 0~CAN_MAX_ID 구조체 순번
id = 각 구조체의 CanID
func = 데이터 수신 시 실행될 함수
*/
void Can_SetID(uint8_t index, uint16_t id, void (*func)(void))
{
    sCan[index].CanID = id;
    sCan[index].CanFlag = 0;
    
    if ( func )
    {
        sCan[index].m_fp = func;
    }
}
 
void Can_TxMessage(uint16_t id, uint8_t length, uint8_t* data)
{
    uint8_t i;
    for ( i = 0 ; i < length ; i ++ )
        TxMessage.Data[i] = data[i];
    
    TxMessage.DLC = length;
    TxMessage.RTR = CAN_RTR_DATA;
      TxMessage.IDE = CAN_ID_STD;
    TxMessage.StdId = id;
    CAN_Transmit(CAN1, &TxMessage);
}
 
void CAN1_RX0_IRQHandler(void)
{
    uint8_t id;
        printf("can");
      CAN_Receive(CAN1, CAN_FIFO0, &RxMessage0);
    CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    
    for ( id = 0 ; id < CAN_MAX_ID ; id ++ )
    {
        if ( sCan[id].CanID == RxMessage0.StdId)
        {
            sCan[id].CanRxMessage = RxMessage0;
            sCan[id].CanFlag = 1;
            if ( sCan[id].m_fp )
            {
                sCan[id].m_fp();
            }
        }
    }
}
 
void test1()
{
  printf("ID 0x700, DLC: %d, data0= %d\r\n", sCan[0].CanRxMessage.DLC, sCan[0].CanRxMessage.Data[3]);
}
void test2()
{
  printf("ID 0x701, DLC: %d, data0= %d\r\n", sCan[1].CanRxMessage.DLC, sCan[1].CanRxMessage.Data[3]);
}
 
 
int main(void)
{
    uint8_t data[4]={0};
    USART1_Configuration();
    Can_Init();
    
    Can_FilterConfig(CAN_FilterMode_IdMask, 00x70000x7f00x0);
    Can_SetID(00x700, test1);
    Can_SetID(10x701, test2);
    
 
    RCC_ClocksTypeDef     RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
    printf("SYS:%d H:%d, P1:%d, P2:%d\r\n",
                                            RCC_Clocks.SYSCLK_Frequency,
                                            RCC_Clocks.HCLK_Frequency,        // AHB
                                            RCC_Clocks.PCLK1_Frequency,        // APB1
                                            RCC_Clocks.PCLK2_Frequency);    // APB2
    
    
    //printf("HELLO WORLD!");
    while(1)
    {
        data[0= 1; data[1= 2; data[2= 3; data[3= 'd';
        Can_TxMessage(0x7004, data);
    }
 
cs


'공부 > stm32' 카테고리의 다른 글

stm32f4 VCP(virtual com port)  (0) 2016.08.30
can통신 신호 분석  (1) 2016.07.27
stm32f4 클럭상태 출력하기  (0) 2016.07.25

stm32f407 현재 클럭 상태를 알고싶을때 사용 할 수 있는 코드


RCC_ClocksTypeDef     RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
printf("SYS:%d H:%d, P1:%d, P2:%d\r\n",
                                            RCC_Clocks.SYSCLK_Frequency,
                                            RCC_Clocks.HCLK_Frequency,         // AHB
                                            RCC_Clocks.PCLK1_Frequency,        // APB1
                                            RCC_Clocks.PCLK2_Frequency);     // APB2
cs


'공부 > stm32' 카테고리의 다른 글

stm32f4 VCP(virtual com port)  (0) 2016.08.30
can통신 신호 분석  (1) 2016.07.27
stm32f4 can 통신 무작정  (2) 2016.07.25

+ Recent posts