|
[GD32F350作品提交] 基于GD32F350的工业控制设备
[复制链接]
本帖最后由 damiaa 于 2018-10-17 15:42 编辑
[GD32F350作品提交] 基于GD32F350的工业控制设备
硬件主要构成:
GD32F350为CPU
16路输入 可以作为按键 也可以作为传感器输入采集 软件捕获电平和(按下,弹起)
16路输出 继电器
串口输出提示信息,也可以和屏进行接口。
软件构成:
GD32基本库
systick.h systick.c 有关systick定时的函数
gd32f3x0_libopt
gd32f3x0_it.h gd32f3x0_it.c 有关定时中断,串口中断,systick中断的函数调用。
comm.h 公共结构的定义 和宏定义
gd32board.h gd32board.c 板子基本输入输出,定时器,串口等设备的初始化,输入输出基本函数定义。
devicecontrol.h devicecontrol.c 软件用到的一些基本函数,比如输入检测,软定时器实现等。
main.c 主函数,所有实现。
主要是针对GD32F350实现一个小型的工业控制主板的基本框架,目前先实现一个小的功能:加工设备的运行(按键,传感器, 输 出继电器控制电机启停,串口输出信息等)。
使用硬件资源:
串口0,1。
systick
定时器1,2
GPIO 输入输出IO口
软件详细实现
1,软定时器:
这个是利用GD32F350硬件定时器1实现N个软定时器,充分利用了CPU的资源,达到了扩充工业控制用定时器功能的目的:
1, comm.h中定义结构
#define SOFTTIMMAX 10
typedef struct
{
uint32_t tim[SOFTTIMMAX]; //10ms*tim
} SOFTTIMERSTR;
devicecontrol.h中申明
uint8_t SetSoftTimer(uint8_t num,uint32_t val);
uint8_t DecSoftTimer(uint8_t num);
uint8_t IfSoftTimer(uint8_t num);
devicecontrol.c中定义:
SOFTTIMERSTR SOFTTIMER;
uint8_t SetSoftTimer(uint8_t num,uint32_t val)//设置定时器值
{
if(num >= SOFTTIMMAX) return 0;
SOFTTIMER.tim[num]=val;
return 1;
}
uint8_t ClrSoftTimer(uint8_t num) //退出定时器
{
if(num >= SOFTTIMMAX) return 0;
SOFTTIMER.tim[num]=0;
return 1;
}
uint8_t DecSoftTimer(uint8_t num)//设置定时器条件下定时器工作
{
if(num >= SOFTTIMMAX) return 0;
if(SOFTTIMER.tim[num] >1)
SOFTTIMER.tim[num] -=1;
return 1;
}
uint8_t IfSoftTimer(uint8_t num)//判断定时器是在定时还是溢出还是退出了。
{
if(num >= SOFTTIMMAX) return 99;
if(SOFTTIMER.tim[num] > 1)
return 1;
if(SOFTTIMER.tim[num] == 1)
return 0;
if(SOFTTIMER.tim[num] == 0)
return 2;
}
devicecontrol.h包含到gd32f3x0_it.c 中gd32f3x0_it.c调用
void TIMER1_IRQHandler()
{
uint8_t i;
for(i=0;i
DecSoftTimer(i);
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
}
main.c使用时包含devicecontrol.h
SetSoftTimer(0,6000);调用软定时器0,并设定时间为6000*10MS
if(IfSoftTimer(0) == 0) 判断 定时器是否溢出。这里定义了SOFTTIMMAX个软定期器可以调用。
软件定时器好处:1,充分利用硬件定时器资源扩充定时器。2,随意扩充定时器。3,代替传统的延时到达系统响应不停滞。
2,输入检测: comm.h中定义结构
typedef struct
{
uint8_t lastedgelevel; //1 high 0 low
uint8_t nowedgelevel; //1 high 0 low
uint8_t act; //result;0x4 no act 0 tolow 1 tohigh
}KEYDEF;
devicecontrol.c中定义:
KEYDEF KeyorIN[16];
void KEYorINCheck(void)
{
uint8_t i,t=16;
for(i=0;i
{
KeyorIN.chktimes <<=1;
if(GetKEYLINEStatus(i)){ KeyorIN.chktimes +=1; }
}
for(i =0;i
{
if((KeyorIN.chktimes & 0xffffffff)==0 )
KeyorIN.nowedgelevel =LOWLEVEL; //low
if((KeyorIN.chktimes & 0xffffffff)==0xffffffff)
KeyorIN.nowedgelevel =HIGHLEVEL; //high
if((HIGHLEVEL == KeyorIN.lastedgelevel)&&(LOWLEVEL == KeyorIN.nowedgelevel)) //down
{
KeyorIN.lastedgelevel =LOWLEVEL;
KeyorIN.act =TOLOW ;
}
if((LOWLEVEL == KeyorIN.lastedgelevel)&&(HIGHLEVEL == KeyorIN.nowedgelevel)) //up
{
KeyorIN.lastedgelevel = HIGHLEVEL;
KeyorIN.act =TOHIGH;
}
}
}
uint8_t IfKeyorIN_LEVEL(uint8_t num)
{
return KeyorIN[num].lastedgelevel;
}
uint8_t IfKeyorIN_ACT(uint8_t num)
{
return KeyorIN[num].act;
}
gd32f3x0_it.c调用
void TIMER2_IRQHandler()
{
KEYorINCheck();
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
}
main.c使用时包含devicecontrol.h有16个输入可以检测 comm.h中定义了
#define IN1 0
#define IN2 1
。。。
#define IN15 14
#define IN16 15
调用入 if(IfKeyorIN_ACT(IN1) == TOLOW) {。。。}
3,输出
gd32board.c中定义 main.c中调用:有16个输出 comm.h中定义了
#define IN1 0
#define IN2 1
。。。
#define IN15 14
#define IN16 15
void gd_output(uint8_t num,uint8_t ONorOff)
{
if(ONorOff)
GPIO_BOP(OUTPUT_PORT[num]) = OUTPUT_PIN[num];
else
GPIO_BC( OUTPUT_PORT[num]) = OUTPUT_PIN[num];
}
如: gd_output(OUT2,ON);//OUT2
4,串口输出提示
gd32board.c中定义 初始化函数,主 main.c中调用,
中断中实现中断函数 主主 main.c中调用输出打印等
void gd_eval_com_init(uint32_t com)
{
。。。
}
void USART1_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_RBNE)){
/* receive data */
uartbuf1.receiver_buffer[uartbuf1.rxcount++] = (usart_data_receive(EVAL_COM1) & 0x7F);
if(uartbuf1.rxcount == uartbuf1.receivesize){
usart_interrupt_disable(EVAL_COM1, USART_INT_RBNE);
}
}
if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_TBE)){
/* transmit data */
usart_data_transmit(EVAL_COM1, uartbuf1.transmitter_buffer[uartbuf1.txcount++]);
if(uartbuf1.txcount == uartbuf1.transfersize){
usart_interrupt_disable(EVAL_COM1, USART_INT_TBE);
}
}
}
void USART2_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(EVAL_COM2, USART_INT_FLAG_RBNE)){
/* receive data */
uartbuf2.receiver_buffer[uartbuf2.rxcount++] = (usart_data_receive(EVAL_COM2) & 0x7F);
if(uartbuf2.rxcount == uartbuf2.receivesize){
usart_interrupt_disable(EVAL_COM2, USART_INT_RBNE);
}
}
if(RESET != usart_interrupt_flag_get(EVAL_COM2, USART_INT_FLAG_TBE)){
/* transmit data */
usart_data_transmit(EVAL_COM2, uartbuf2.transmitter_buffer[uartbuf2.txcount++]);
if(uartbuf2.txcount == uartbuf2.transfersize){
usart_interrupt_disable(EVAL_COM2, USART_INT_TBE);
}
}
}
如:main.c中调用 printf("\n\r\turn on!!!");
5,中程序中工业控制流程设计(采用状态机)
int main(void)
{
//systick_config();
gd_eval_led_init(LED1);
gd_eval_led_init(LED2);
gd_eval_led_init(LED3);
gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
gd_KeyorIn_initN();
gd_output_initN();
timer1_init();
timer2_init();
/* USART interrupt configuration */
//nvic_irq_enable(USART0_IRQn, 0, 0);
nvic_irq_enable(USART1_IRQn, 0, 0);
gd_eval_com_init(EVAL_COM2);
/* enable USART TBE interrupt */
usart_interrupt_enable(EVAL_COM2, USART_INT_TBE);
/* wait until USART send the transmitter_buffer *
usart_interrupt_enable(EVAL_COM2, USART_INT_RBNE);
beginwork1();
while (1)
{
work1();
}
}
void beginwork1(void) //
{
gd_output(OUT1,OFF);//OUT1 传动电机
gd_output(OUT2,OFF);//OUT2 下压电机
gd_output(OUT3,OFF);//OUT3 卸载电机
workstats =1;
}
void work1(void)
{
switch(workstats)
{
case stats1:
if(IfKeyorIN_ACT(IN1) == TOLOW) // 分配启动键为IN1
{
workstats =2;
printf("\n\r\turn on!!!");
gd_eval_led_on(LED2);
gd_output(OUT1,ON);//OUT1
}
else
{
gd_eval_led_off(LED2);
}
break;
case stats2:
if(IfKeyorIN_ACT(IN3) == TOLOW) //分配IN3为前置传感器
{
gd_output(OUT2,ON);//OUT2
SetSoftTimer(0,6000);//
gd_output(OUT2,OFF);//OUT2
workstats =3;
printf("moto1 on!!!");
}
if(IfKeyorIN_ACT(IN2) == TOLOW) //分配IN2为停止键
{
workstats =5;ClrSoftTimer(0);
}
if(IfSoftTimer(0) == 0)
{workstats =3; ClrSoftTimer(0);}
break;
case stats3:
if(IfKeyorIN_ACT(IN4) == TOLOW) //分配IN4为后置传感器
{
printf("moto2 on!!!");
gd_output(OUT2,OFF);//OUT2
gd_output(OUT3,ON);//OUT3
SetSoftTimer(0,6000);//
gd_output(OUT3,OFF);//OUT3
}
if(IfKeyorIN_ACT(IN2) == TOLOW) //
{
workstats =5;ClrSoftTimer(0);
}
if(IfSoftTimer(0) == 0)
{workstats =4; ClrSoftTimer(0);}
break;
case stats4:
gd_output(OUT1,OFF);//OUT1
gd_output(OUT2,OFF);//OUT2
gd_output(OUT3,OFF);//OUT3
workstats =1;
break;
case stats5:
printf("moto1,moto2,moto3 off!!!");
gd_output(OUT1,OFF);//OUT1
gd_output(OUT2,OFF);//OUT2
gd_output(OUT3,OFF);//OUT3
gd_eval_led_on(LED3);
delay_ms(100);
gd_eval_led_off(LED3);
workstats =1;
break;
default:
workstats =1;
break;
}
}
总结:该状态机形式的工业控制设备框架灵活多变,调试容易,小巧灵活。很容易构成一台新的工业控制设备。
程序附件:
GD32F3x0_Firmware_Library_V1.0.0_Colibri-F350aa.zip
(320.16 KB, 下载次数: 9)
6,硬件原理图相关:
输入电路
输出电路
串口电路
CPU电路:目前采用通用的核心板。
电路原理图附件:
I.SchDoc
(334 KB, 下载次数: 5)
O.SchDoc
(124 KB, 下载次数: 5)
uarttt.SchDoc
(153 KB, 下载次数: 5)
|
|