找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 571|回复: 2
打印 上一主题 下一主题
收起左侧

Eclipse工程 STM32单片机通用执行器控制程序 节气门控制

[复制链接]
跳转到指定楼层
#
ID:282577 发表于 2023-6-12 10:32 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "tim1.h"
  4. #include "pwm.h"
  5. #include "stdio.h"
  6. #include "usart.h"
  7. //#include "key.h"
  8. #include "iic.h"
  9. #include "adc.h"
  10. #include "LCD12864.h"
  11. #include "rs485.h"
  12. #include "Lin.h"
  13. #include "TLE7209.h"
  14. #include "dma.h"
  15. #define ID 0X30
  16. #define SEND_BUF_SIZE 40        //发送数据长度,最好等于sizeof(TEXT_TO_SEND)+2的整数倍.
  17. u8 SendBuff[SEND_BUF_SIZE];        //发送数据缓冲区
  18. u8 TEXT_TO_SEND[]={'D','C',50,51,52,53,54,56,49,50,51,52,53,54,56,49,50,51,52,'m'};
  19. u16 pwm[]={10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,510,520,530,540,550,560,570,580,590,600,610,620,630,640,650,660,670,680,690,700,
  20.                  810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,960,970,980,990,1000};
  21. u16 pwm_wal;
  22. u8 C[20];
  23. u32 Time,Cylce;
  24. u16 data_flag=1;
  25. u16 RS485[900];
  26. u16 RS485_data[300];
  27. u16  R_CURVE[300];
  28. u8 Cur_Addr[] = { 0x95, 0x8D, 0X9D };
  29. u8 rs485buf2[20] ;
  30. u8 Address_number;
  31. u16 Air_flow_high8bit = 0, Air_flow_low8bit = 0, Air_flow_CRC = 0;
  32. u32 flowdata = 0, mearsured_flowdata = 0, flow_date_H, flow_date_D, flow_date_S,flow_date_S_1, flow_date_S_2;
  33. u32 traget_speed_10000, traget_speed_1000, traget_speed_100, traget_speed_10,traget_speed_1;
  34. u32 actual_speed_10000, actual_speed_1000, actual_speed_100, actual_speed_10,actual_speed_1;
  35. u32 supply_voltage_10, supply_voltage_1;
  36. u32 supply_current_100, supply_current_10, supply_current_1;
  37. u32 temperature_100, temperature_10, temperature_1;
  38. u32 Analog_IN0_1000, Analog_IN0_100, Analog_IN0_10, Analog_IN0_1;
  39. u8 num, addr = 0;
  40. u16 AA, BB, CC;
  41. int Number_value =0;
  42. int Received_Number_value = 200;
  43. u8  TIM4CH1_CAPTURE_STA=0;        //输入捕获状态
  44. u16        TIM4CH1_CAPTURE_VAL,CAP_F;        //输入捕获值
  45. u32 T;
  46. u32 duty;
  47. u8 key = 0;
  48. u16 Total_time,len,t,times,totaldata;
  49. u32 app_cycle = 0;
  50. u16 Counter = 0;
  51. unsigned int rs485buf[6], rs485buf1[60];
  52. float Temp=1, Temp1, Pre_error = 0, Pre_Derror = 0, V_kp = 440, V_ki = 0.000001,V_kd = 0, V_change = 0, Volaegre_set = 4.2;
  53. int V_value, V_value1, pwm_number = 50, pwm_number1 = 50, Cursor_flag = 0,KEY_Up_flag = 0, KEY_Down_flag = 0, ALL_DATA = 0, Temp2 = 0, Temp3 = 0;
  54. float error1, d_error, dd_error;
  55. int teatdata = 1, teatdata1 = 1, readdata = 1000, valueall = 1000, second = 0,second1 = 0, minute = 0, hour = 0, minute1 = 0, hour1 = 0;
  56. unsigned char value1, value2;
  57. unsigned long int Sin1[] = { 100,200  };
  58. unsigned int kk, flag_break, Pump_speed1 = 500, Pump_speed2 = 500,Pump_speed1_VIEW = 0, Pump_speed2_VIEW = 0, Number_value_VIEW;
  59. unsigned int traget_speed = 0, actual_speed = 0, traget_speed1 = 0,actual_speed1 = 0, supply_voltage1 = 0, supply_current1 = 0,temperature1, voltage_status = 0, speed_status = 0, current_status = 0,
  60.                 temperature_status = 0, roling_counter = 0, Stall_detection_status = 0,block_eeeor = 0, inter_error = 0, Response_error;
  61. unsigned long int Error_sattus = 0, running_mode = 0, position_feedback = 0,move_status = 0, speed_level = 0, Temperature_status = 0,
  62.                 supply_voltage_status = 0, Lin_communication_status = 0;
  63. float Analog_IN0 = 0, Analog_IN00 = 0, MMM, MMMM, MMMMM, supply_voltage = 0,supply_current, temperature, Analog_IN2 = 0;
  64. unsigned long int change1, change2, Set_point, position = 0xff, cycle;
  65. float T_temp=0,T_temp_T=1,T_last_temp;
  66. void lcd_sfm(unsigned int add, int data)    //显示位置和数据
  67. {
  68.         unsigned char qian, bai, shi, ge;
  69.         qian = data / 1000;
  70.         bai = (data - qian * 1000) / 100;
  71.         shi = (data - qian * 1000 - bai * 100) / 10;
  72.         ge = (data - qian * 1000 - bai * 100 - shi * 10) % 10;
  73.         Write_Com(add);
  74.         //Write_Date(0x30 + qian);
  75.         Write_Date(0x30 + bai);

  76.         Write_Date(0x30 + shi);
  77.         Write_Date(0x2e);
  78.         Write_Date(0x30 + ge);
  79. }

  80. void lcd2_sfm(unsigned char add, int data)    //显示位置和数据
  81. {
  82.         unsigned char qian, bai, shi, ge;
  83.         qian = data / 1000;
  84.         bai = (data - qian * 1000) / 100;
  85.         shi = (data - qian * 1000 - bai * 100) / 10;
  86.         ge = (data - qian * 1000 - bai * 100 - shi * 10) % 10;
  87.         Write_Com(add);
  88.         //Write_Date(0x30 + 0);
  89.         //Write_Date(0x30 + qian);
  90.         //Write_Date(0x30 + bai);
  91.         //Write_Date(0x30 + shi);
  92.         Write_Date(0x30 + ge);
  93. }

  94. void lcd3_sfm(unsigned char add, int data)    //显示位置和数据
  95. {
  96.         unsigned char wan, qian, bai, shi, ge;
  97.         wan = data / 10000;
  98.         qian = (data - wan * 10000) / 1000;
  99.         bai = (data - wan * 10000 - qian * 1000) / 100;
  100.         shi = (data - wan * 10000 - qian * 1000 - bai * 100) / 10;
  101.         ge = (data - wan * 10000 - qian * 1000 - bai * 100 - shi * 10) % 10;
  102.         Write_Com(add);
  103.         Write_Date(0x30 + wan);
  104.         Write_Date(0x30 + qian);
  105.         Write_Date(0x30 + bai);
  106.         Write_Date(0x30 + shi);
  107.         Write_Date(0x30 + ge);
  108. }
  109. void lcd1_sfm(unsigned char add, int data)    //显示位置和数据
  110. {
  111.         unsigned char qian, bai, shi, ge;
  112.         qian = 0;
  113.         bai = (data - qian * 1000) / 100;
  114.         shi = (data - qian * 1000 - bai * 100) / 10;
  115.         ge = (data - qian * 1000 - bai * 100 - shi * 10) % 10;
  116.         Write_Com(add);
  117.         Write_Date(0x30 + qian);
  118.         Write_Date(0x2e);
  119.         Write_Date(0x30 + bai);
  120.         Write_Date(0x30 + shi);
  121.         Write_Date(0x30 + ge);
  122. }
  123. float Voltage_PID(float Volatage_ref, float Voltage_back) {
  124.         float error2;
  125.         AA = Get_Adc_Average(8, 10);
  126.         //Temp =AA*3.3*10/4096;;
  127.         //Temp = ((USART_RX_BUF[0]-48)*10+USART_RX_BUF[1]-48)/10;
  128.         Temp =3;
  129.         BB = Get1_Adc_Average(9, 40);
  130.         Temp1 = BB * 3.3 * 2 / 4096;
  131.         error1 = Volatage_ref - Voltage_back;
  132.         d_error += error1;
  133.         Pre_error = error1 - error2;
  134.         error2 = error1;
  135.         if ((error1 >= -5) && (error1 < 5))
  136.         {
  137.         V_change = V_kp * error1 + V_ki * d_error + V_kd * Pre_error;
  138.         }
  139.         return (V_change);
  140. }

  141. void TIM4_Capture_Init(u16 arr,u16 psc)
  142. {
  143. RCC->APB1ENR|=1<<2;           //TIM4 时钟使能
  144. RCC->APB2ENR|=1<<3;            //使能PORTb时钟

  145. GPIOB->CRH&=0XFFFFFF0F;        //Pb9 清除之前设置
  146. GPIOB->CRH|=0X00000080;        //PB9 输入
  147. GPIOB->ODR|=1<<9;                //PB9 下拉

  148. TIM4->ARR=arr;                  //设定计数器自动重装值
  149. TIM4->PSC=psc;                  //预分频器

  150. TIM4->CCMR2|=1<<8;                //CC1S=01         选择输入端 IC1映射到TI1上
  151. TIM4->CCMR2|=0<<12;         //IC1F=0000 配置输入滤波器 不滤波
  152. TIM4->CCMR2|=0<<10;         //IC2PS=00         配置输入分频,不分频

  153. TIM4->CCER|=0<<13;                 //CC1P=0        上升沿捕获
  154. TIM4->CCER|=1<<12;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中

  155. TIM4->DIER|=1<<4;           //允许捕获中断
  156. TIM4->DIER|=1<<0;           //允许更新中断
  157. TIM4->CR1|=0x01;            //使能定时器4
  158. MY_NVIC_Init(1,3,TIM4_IRQn,2);//抢占0,响应0,组2
  159. }
  160. void TIM3_Int_Init(u16 arr, u32 psc) {
  161.         RCC->APB1ENR |= 1 << 1;        //TIM3时钟使能
  162.         TIM3->ARR = arr;          //设定计数器自动重装值//刚好1ms
  163.         TIM3->PSC = psc;          //预分频器7200,得到10Khz的计数时钟
  164.         TIM3->DIER |= 1 << 0;   //允许更新中断
  165.         TIM3->CR1 |= 0x01;    //使能定时器3
  166.         MY_NVIC_Init(3, 2, TIM3_IRQn, 2);    //抢占31,子优先级23,组2
  167. }

  168. void TIM2_PWM_Init(u16 arr, u32 psc) {
  169.         RCC->APB1ENR |= 1 << 0;        //TIM23时钟使能
  170.         TIM2->ARR = arr;          //设定计数器自动重装值//刚好1ms
  171.         TIM2->PSC = psc;          //预分频器7200,得到10Khz的计数时钟
  172.         TIM2->DIER |= 1 << 0;   //允许更新中断
  173.         TIM2->CR1 |= 0x01;    //使能定时器3
  174.         MY_NVIC_Init(1, 3, TIM2_IRQn, 2);    //抢占1,子优先级3,组2
  175. }
  176. //............12864 Course view............//
  177. void Dis_Cur() {
  178.         Write_Com(Cur_Addr[Address_number]);
  179.         delay_ms(100);
  180.         Write_Com(0x0e);
  181.         delay_ms(100);
  182.         Write_Com(0x0C);
  183. }

  184. int main(void) {
  185.         u16 i;
  186.         u8 t=0;
  187.         u8 j,mask=0;


  188.         Stm32_Clock_Init(9);        //系统时钟设置
  189.         delay_init(72);
  190.         uart1_init(72, 19200);         //串口初始化为115200
  191.         uart2_init(36, 9600);         //串口初始化为115200

  192.         KEY_Init();
  193.         PWM_Init();
  194.         Adc_Init();
  195.         Init_12864();
  196.         Init_TLE7209();
  197.     IIC_Init();
  198.         TLE7209_SCK = 1;
  199.         TLE7209_CS = 1;
  200.         TLE7209_DIS = 0;
  201.         TLE7209_EN = 1;
  202.         LCD12864xie(0,0,"GPA Control Box");
  203.         LCD12864xie(0,1,"SP:");
  204.         LCD12864xie(4,1,"FP:");
  205.         TIM3_Int_Init(1000, 71);         //10Khz的计数频率,计数5K次为500ms
  206.         TIM4_Capture_Init(0XFFFF,71);
  207.         TIM_Init(720, 999, 300);
  208.         TIM2_PWM_Init(10000, 7199);

  209.         i=0;
  210.         while (1)
  211.         {   if(TIM4CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
  212.                 {
  213.                         T_temp=TIM4CH1_CAPTURE_STA&0X3F;
  214.                         T_temp*=65536;//溢出时间总和
  215.                         T_temp+=TIM4CH1_CAPTURE_VAL;//得到总的高电平时间

  216.                         TIM4CH1_CAPTURE_STA=0;//开启下一次捕获
  217.                         if(CAP_F==1) {//整个周期
  218.                                 T_temp_T=T_temp;
  219.                                 T=(100000000/T_temp_T/100+0.5);//得到周期
  220.                                 duty=(T_last_temp*100/T_temp_T+0.5);//得到占空比  duty%
  221.                         }
  222.                         CAP_F++;
  223.                         if(CAP_F>1)
  224.                                 {CAP_F=0;//捕获高电平时间和周期时间的转换标志位
  225.                                 }
  226.                         T_last_temp=T_temp;
  227.                 }


  228.                 TLE7209_CS = 1;
  229.                 TLE7209_SCK = 1;
  230.                 //Write_Com(0x01);                //清屏
  231.                 TLE7209_SCK = 0;                 //一个脉冲保存数据
  232.                 TLE7209_CS = 0;
  233.                 delay_us(10);
  234.                 value1 = TLE7209SentByte(0x09);
  235.                 value2 = TLE7209SentByte(0x00);
  236.                 TLE7209_CS = 1;
  237.                 TLE7209_SCK = 1;
  238.                 delay_us(10);
  239.                 TLE7209_SCK = 0;
  240.                 TLE7209_CS = 0;
  241.                 delay_us(10);
  242.                 TLE7209_CS = 1;
  243.                 TLE7209_CS = 0;
  244.                 lcd_sfm(0x92, Temp1*20000);
  245.                 lcd_sfm(0x96, Temp*20000);
  246.                 lcd3_sfm(0x9a,duty);
  247.                 lcd3_sfm(0x9d, T);
  248.         if (value1 != 255)
  249.                 {
  250.                         TLE7209_EN = 0;
  251.                         delay_us(10);
  252.                         TLE7209_EN = 1;
  253.                         delay_us(10);
  254.                 }

  255.                 }
  256. }

  257. //定时器5中断服务程序
  258. void TIM4_IRQHandler(void)
  259. {
  260.         u16 tsr;
  261.         tsr=TIM4->SR;
  262.          if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
  263.         {if(tsr&0X01)//溢出
  264.         {
  265.                 if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
  266.                 {
  267.                         if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
  268.                         {
  269.                                 TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
  270.                                 TIM4CH1_CAPTURE_STA=0XFFFF;
  271.                         }else TIM4CH1_CAPTURE_STA++;
  272.                 }
  273.         }

  274.                 if(tsr&(1<<4))
  275.                 {
  276.                         if(TIM4CH1_CAPTURE_STA&0X40)                //捕获到一个下降沿
  277.                         {
  278.                                 TIM4CH1_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
  279.                             TIM4CH1_CAPTURE_VAL=TIM4->CCR4;        //获取当前的捕获值.
  280.                                  TIM4->CCER&=~(1<<13);                        //CC1P=0 设置为上升沿捕获
  281.                         }else                                                                  //还未开始,第一次捕获上升沿
  282.                         {
  283.                                 TIM4CH1_CAPTURE_STA=0;                        //清空
  284.                                 TIM4CH1_CAPTURE_VAL=0;
  285.                                 TIM4->CNT=0;
  286.                                 TIM4CH1_CAPTURE_STA|=0X40;                //标记捕获到了上升沿

  287.                                 if(CAP_F==0)
  288.                                  TIM4->CCER|=1<<13;                                 //CC1P=1 设置为下降沿捕获
  289.                                 else
  290.                                 TIM4->CCER&=~(1<<13);                        //CC1P=0 设置为上升沿捕获
  291.                         }
  292.                 }
  293.                  }
  294.         TIM4->SR=0;//清除中断标志位
  295. }

  296. void TIM2_IRQHandler(void) {
  297.         if (TIM2->SR & 0X0001)                 //溢出中断
  298.                         {pwm_number = 0.1 * pwm_number +  0.6*Voltage_PID(Temp, Temp1);

  299.                         if (pwm_number < -50) {
  300.                                 pwm_number = -50;
  301.                         }
  302.                         if (pwm_number > 50) {
  303.                                 pwm_number = 50;
  304.                         }

  305.                         pwm_number1 = 50 + pwm_number;
  306.                         pwm_wal++;
  307.                         if(pwm_wal>=89)
  308.                         {pwm_wal=0;}
  309.                         TIM_Init(720, 999,  pwm[pwm_wal]);

  310.                          }
  311.         TIM2->SR &= ~(1 << 0);                 //清除中断标志位
  312. }
复制代码

仅仅提供Eclipse代码下载,仅供参考,可能有错: GPA Control box - Test.7z (332.17 KB, 下载次数: 10)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2023-6-21 16:48 | 只看该作者
PID算法的灵魂在于如何找到P、I、D这三个参数的具体数值,至于软件实现PID太简单了,没有分享的价值。
回复

使用道具 举报

楼主
ID:270740 发表于 2023-6-20 11:58 | 只看该作者
根本就打不开,不完整,怀疑你从哪里抄来的
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表