2141 views|2 replies

6841

Posts

11

Resources
The OP
 

[AT-START-F425 Review] CAN and N32G45 communication example - controlling the servo by stacking blocks. [Copy link]

 

[Preface] Previously, I had already completed the temperature and humidity, RTC display, and used a single machine to debug the servo control. According to my evaluation plan, I used AT32 to communicate with N32G45 and STM32. Today, I completed the dual-machine CAN communication.

[Hardware Construction] AT32F425 is the master controller, N32G45 is the command sender, and the CAN analyzer of STM32F103 is the monitor. Since AT32F425 and N32G45 are not equipped with CAN to TTL chips, I used the transceiver I used for Fudan Micro Evaluation. Fortunately, I bought two at that time, one was used and the other was gathering dust... This time, I finally used both. (Since it is connected by Dubinding wire, please forgive the wires for being a bit messy).

The protagonist of this communication is to use the three buttons of N32G45 to control the servo connected to AT32F425 to perform 0, 90 and 180 degree rotation demonstration. The signal control of the servo is controlled by TMR1 CH1 (PA8). Because the USB power supply is afraid that the current of the motor is not enough, I asked for my GPD DC power supply:

[Software environment] RT_Tread Studio opens the N32G45 and AT32F425 programming environment.

[Main procedures] 1. Read the status of three buttons of N32G45:

void init_Key(void)
{
    /* 按键1、2、3引脚为输入模式 */
    rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(KEY2_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(KEY3_PIN_NUM, PIN_MODE_INPUT_PULLUP);
}
typedef struct {
    uint8_t Key1_state;
    uint8_t Key2_state;
    uint8_t Key3_state;
} _key_state;
_key_state key_state;
static void key_scan(void)
{
    uint16_t id = 0x400;
    uint8_t dat[8] = {0};
    rt_err_t can_send_state;
    key_state.Key1_state  = rt_pin_read(KEY1_PIN_NUM);
    key_state.Key2_state  = rt_pin_read(KEY2_PIN_NUM);
    key_state.Key3_state  = rt_pin_read(KEY3_PIN_NUM);
    if (key_state.Key1_state == 0 || key_state.Key2_state == 0 || key_state.Key3_state ==0) {
            dat[0] = key_state.Key1_state;
            dat[1] = key_state.Key2_state;
            dat[2] = key_state.Key3_state;
            can_send_state = can1_send_dat(id,dat);
            if (can_send_state != RT_EOK) {
                rt_kprintf("send dat fail ERROR:%d\n" , can_send_state );
                rt_thread_mdelay(100);
            }
        }

}

N32G45 sends CAN data:

rt_err_t can1_send_dat(uint16_t send_id,uint8_t *dat)
{
    struct rt_can_msg msg = {0};
    msg.id =  send_id;              /* ID 为 0x123 */
    msg.ide = RT_CAN_STDID;     /* 标准格式 */
    msg.rtr = RT_CAN_DTR;       /* 数据帧 */
    msg.len = 8;                /* 数据长度为 8 */
    /* 待发送的 8 字节数据 */
    msg.data[0] = dat[0];
    msg.data[1] = dat[1];
    msg.data[2] = dat[2];
    msg.data[3] = dat[3];
    msg.data[4] = dat[4];
    msg.data[5] = dat[5];
    msg.data[6] = dat[6];
    msg.data[7] = dat[7];
    /* 发送一帧 CAN 数据 */
    int size = rt_device_write(can1_dev, 0, &msg, sizeof(msg));
    if (size < 0)
    {
        rt_kprintf("can1 dev write data failed rc:%d\n",size);
        return RT_ETIMEOUT;
    }
    return RT_EOK;
}

N32G45 adds the task of sending CAN:

    tid_key_scan = rt_thread_create("key_scan",
            thread1_entry,
            RT_NULL, 512, THREAD_PRIORITY, THREAD_TIMESLICE);
    if (tid_key_scan != RT_NULL) {
        rt_thread_startup(tid_key_scan);
    }

After the N32G45 program is written, download it to the development board and capture data on the CAN analysis after pressing a button:

【AT32F425can data reception and processing】

1. Add the servo driver files rudder.h and rudder.c: configure timer 1, PA8 outputs 50Hz waveform (for details, see my previous post: [New reminder] [AT-START-F425 evaluation] TMR servo driver - domestic chip exchange - Electronic Engineering World Forum (eeworld.com.cn) )

#ifndef __RUDDER_H
#define __RUDDER_H
#include "at32f425.h"

void rudder_init(void);
void set_rudder(uint8_t angle);

#endif
#include "rudder.h"
#include "at32f425_board.h"
#include "at32f425_clock.h"
#include "rtthread.h"

void rudder_init(void)
{
	uint32_t timer_period = 0;
  uint16_t channel1_pulse = 0;
	gpio_init_type  gpio_init_struct = {0};
	tmr_output_config_type tmr_output_struct;
  crm_clocks_freq_type crm_clocks_freq_struct = {0};
	crm_clocks_freq_get(&crm_clocks_freq_struct);
	 /* enable tmr1/gpioa/gpiob clock */
  crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
	
	/* timer1 output pin Configuration */
  gpio_init_struct.gpio_pins = GPIO_PINS_8 ;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOA, &gpio_init_struct);


  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_2);
	
	timer_period = (crm_clocks_freq_struct.sclk_freq/12000) - 1;
	
 	tmr_base_init(TMR1, timer_period, 229);
  tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);

  /* channel 1 in output mode */
  tmr_output_default_para_init(&tmr_output_struct);
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
  tmr_output_struct.oc_idle_state = TRUE;
  tmr_output_struct.occ_output_state = TRUE;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_idle_state = FALSE;
  
  /* channel 1 */
  tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
  tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1_pulse);
  

  /* output enable */
  tmr_output_enable(TMR1, TRUE);
  
  /* enable tmr1 */
  tmr_counter_enable(TMR1, TRUE);
	
}

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] 设置舵机角度
  * @param   angle: 角度值  1-180度
  *         
  *         
  * @param  
  * @param  
  * @retval none
  */

void set_rudder(uint8_t angle)
	{
		uint16_t pluse;
		if(angle >=180)
		{
			pluse = 229 + 790;
		}
		else if(angle == 0)
		{
			pluse = 229;
		}
		else{
			pluse = (uint16_t)(((uint32_t)angle * 795)/180) + 229 ;
		}
		tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, pluse);
		//rt_thread_mdelay(100);
	}

Director adds monitoring CAN program:

static void tid_rudder_entry(void *parameter)
{
	
	while(1)
	{
		if(rud_engle.flage == 1)
		{
			rud_engle.flage = 0;
			set_rudder(rud_engle.angle);
			rt_thread_mdelay(200);
			
		}
		rt_thread_mdelay(5);
	}
}

  tid_rudder = rt_thread_create("RUDDER",
                            tid_rudder_entry, RT_NULL,
                            KEY_THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);
    /* 如果获得线程控制块,启动这个线程 */
    if (tid_rudder != RT_NULL)
        rt_thread_startup(tid_rudder);

Then it's OK, see the effect in the video.

[Feelings] The CAN communication of AT32F425 is easy to use, and the dual-machine communication is smooth, of course, this is still due to the RT-Thread operating system. There is no need to consider the complex logic processing of the bare machine. Of course, there are still many details that have not been handled well. During this period, I get up at 6 o'clock in the morning, plus the time after work, my life is a straight line, going to work, going home, studying, writing code, debugging, writing reports, my life is fulfilling, and I feel that there is not enough time. Tomorrow is a holiday, so I can do my homework well.



This post is from Domestic Chip Exchange
 
 

6841

Posts

11

Resources
2
 
This concludes the CAN evaluation of the AT32F425 development board. The next step is to learn how to use USB.
This post is from Domestic Chip Exchange
 
 
 

6841

Posts

11

Resources
3
 

CAN transceiver modules are in stock, and we hope that the next development board will continue to make them shine:

This post is from Domestic Chip Exchange
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Featured Posts
Huawei Telecom Basic Knowledge Question Bank

Basic Telecommunications Knowledge Question Bank (The following questions can be asked in the form of fill-in-the-blank, ...

Hardware Design Manual

Hardware Design Manual

MATLAB APP Designer serial port debugging tool writing

This post was last edited by lb8820265 on 2019-5-9 23:11 Previously, we introduced two ways to use VC6 to make serial ...

MSP430 standby power consumption problem

Recently, due to project reasons, I used TI's MSP430F149 microcontroller. During the use, I encountered some problems wi ...

Video explains the triggering modes of oscilloscopes and what they mean

The principle and usage of each trigger mode are explained in the form of video, including edge trigger, pulse width tri ...

ssd1306 Chinese and picture display

This post was last edited by lemon1394 on 2021-8-17 23:19 I have found many Chinese displays of ssd1306 introduced on t ...

Embedded Qt-Control Hardware: Slide bar controls RGB lights

The previous articles introduced Qt routines, which are all hardware-independent and can run on both Windows and embed ...

Live broadcast of STM32 Global Conference at 10 am today [send development board and gifts]

With STM32, STMicroelectronics is committed to helping developers around the world build smarter, more connected and mor ...

What is the core technology in the battery management system of new energy vehicles?

Simply put, the core content of battery management is SOC (battery state of charge) and SOH (battery state of health). ...

XD08M3232 is a domestically produced 8-bit high-performance Flash proximity sensing microcontroller with an enhanced 1T8051 core.

XD08M3232 is a domestically produced 8-bit high-performance Flash proximity sensing microcontroller with an enhanced 1T8 ...

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list