2322|2

7048

帖子

11

TA的资源

版主

楼主
 

【AT-START-F425测评】CAN与N32G45通讯实例—堆积木之控制舵机。 [复制链接]

 

【前言】前面积木堆到了温湿度、RTC显示,又用单机调试了舵机的控制。根据我的评测计划是用AT32与N32G45以及STM32进行通信。今天堆积木到了双机CAN通信。

【硬件搭建】AT32F425为主控方,N32G45为指令发送,STM32F103的CAN分析仪为监控方。由于AT32F425、N32G45没有配置CAN转TTL芯片,所以请出了我原来用于复旦微测评的收发器,还好当时我买了两块,备着一块使用,另一块吃灰的。。。这次终于两块都用上了。(由于用的是杜绑线连接,原谅线有点乱)。

   这次通信的主角是用N32G45的三个按键来控制接在AT32F425上的舵机进行0度、90度、180度的旋转演示。舵机的信号控制由TMR1 CH1(PA8)来控制,因为USB供电驱动电机怕有电流不够,所以请出了我的GPD直流电源:

                     

【软件环境】RT_Tread Studio开启N32G45、AT32F425编程环境。

【主要程序】1、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发送CAN数据:

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加入发送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);
    }

N32G45程序编写结束后下载到开发板,按键后在CAN分析上捕获数据:

 【AT32F425can数据接收与处理】

1、添加舵机驱动文件rudder.h、rudder.c:配置定时器1,PA8输出50Hz波形(具体见我上一篇贴子:【新提醒】【AT-START-F425测评】TMR 舵机驱动 - 国产芯片交流 - 电子工程世界-论坛 (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);
	}

主任添加监控CAN程序:

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);

然后就OK了,效果见视频。

【感受】AT32F425的CAN通信上手还算顺手,双机通信实现起来顺利,当然这还是归功于RT—Thread的操作系统。不用考虑祼机的复杂逻辑处理。当然还有许多细节没有处理好。这段时间都是早上6点起来,加上下班时间,生活两点一线,上班下班,学习,写代码,调试,写报告,生活充实,感觉时间不够用。明天马上放假了,可以好好写作业。



 

 

点赞 关注
 
 

回复
举报

7048

帖子

11

TA的资源

版主

沙发
 
到此AT32F425开发板CAN评测告一段落,下一步,学习使用USB的使用。
 
 
 

回复

7048

帖子

11

TA的资源

版主

板凳
 

CAN收发模块入库,期待下一个开发板能让他们继续发光发热:

   

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表