|
開發(fā)的氨氮檢測儀,采用CAN總線輸出,源程序和PCB見附件:
技術(shù)參數(shù)如下:
技術(shù)參數(shù) 量程:0~100ppm(量程可調(diào)) 精度:0.1ppm 輸出信號:CAN總線 傳輸協(xié)議:Modbus RTU 485波特率:9600(默認) CAN頻率:500K(默認) 溫度范圍:0-80℃ 溫度補償:自動補償 校準(zhǔn):命令方式(軟件校準(zhǔn)) 工作電壓:5V/12V 電纜長度:標(biāo)配5米
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
QQ截圖20190625170137.jpg (63.97 KB, 下載次數(shù): 42)
下載附件
2019-6-25 17:02 上傳
0.png (48.2 KB, 下載次數(shù): 43)
下載附件
2019-6-25 22:02 上傳
0.png (5.07 KB, 下載次數(shù): 53)
下載附件
2019-6-25 22:02 上傳
QQ截圖20190625170348.jpg (105.42 KB, 下載次數(shù): 44)
下載附件
2019-6-25 17:04 上傳
單片機源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "adc.h"
- #include "dma.h"
- #include "can.h"
- #include "rs485.h"
- #include "math.h"
- #include "stmflash.h"
- //要寫入到STM32 FLASH的字符串?dāng)?shù)組
- u16 flash[10],read[10];//第一位判斷是否是初始設(shè)置
- #define SIZE sizeof(write) //數(shù)組長度
- #define FLASH_SAVE_ADDR 0X08040000 //設(shè)置FLASH 保存地址(必須為偶數(shù),且其值要大于本代碼所占用FLASH的大小+0X08000000)
- u16 get[20000];
- float n,m;
- int a,phase,crc,rsp;
- int array[]={115200,57600,38400,28800,19200,14400,9600,4800,2400,1200};
- u16 brq;
- int main(void)
- {
- u8 rs485[8],send485[8],len;
- u8 cnt=0;
- u8 canbuf[8],canget[8];
- int i;
- float temp,nh;
- delay_init();
- uart_init(9600); //串口初始化為9600
- LED_Init();
- if(flash[0]==10)RS485_Init(array[flash[4]]);
- else RS485_Init(9600); //初始化RS485
- MYDMA_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)get,1904);//DMA1通道1,外設(shè)為串口1,存儲器為SendBuff,長度應(yīng)為轉(zhuǎn)換通道數(shù)×轉(zhuǎn)換次數(shù)
- //采樣952個點,50hz信號 20ms一周期,采樣952個點 約為21us采樣一次,即12Mhz頻率 239.5+12.5個周期252 252=12*21
- Adc_Init();
- DMA_Cmd(DMA1_Channel1, ENABLE); //使能ADC DMA1 所指示的通道
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉(zhuǎn)換啟動功能
- STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)flash,10);
- if(flash[0]==10)CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,flash[3],CAN_Mode_Normal);
- else
- CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_Normal);//36M/((8+9+1)*4)=500Kbps,brp可以設(shè)置從0~1024
- while(1)
- {
-
- // while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);作為保留 防止第一位數(shù)據(jù)丟失
- //MYDMA_Enable(DMA1_Channel1);
- LED1=!LED1;
- for(a=0;a<100;a++) //電壓值求均值,疊加100次再除以100
- {
- for(i=0;i<1902;i+=2)
- {
- n+=get[i]*get[i];
- }
- n=sqrt(n/952);
- nh+=n*(3.3/4096);
- n=0;
- }
- printf("nh4 is %f\r\n",nh/100);
- if(nh<51.3)
- temp=1.01*nh-41.814;
- else temp=12*nh-614;
- printf("nh4 is %f\r\n",temp);
- nh=0;
- // for(i=1;i<11;i+=2)
- // {
- // printf("wendu is %f\r\n",(float)get[i]*(3.3/4096));
- // m+=get[i]*get[i];
- // }
- // m=sqrt(m/952);
- // printf("wendu is %f\r\n",(float)(m/100)*(3.3/4096));
- // m=0;
- canbuf[2]=temp;
- temp-=canbuf[2];
- temp*=100;
- canbuf[3]=temp;
- LED0=!LED0;
- RS485_Receive_Data(rs485,&len);
- if (rs485[0]==0xad)
- {
- switch (rs485[1])
- {
-
- case 0x02: //設(shè)置485頻率
- send485[0]=0xad;
- send485[1]=0x02;
- rsp=(int)rs485[3];
- if(rsp<0&&rsp>9) {send485[2]=0x11; //如頻率設(shè)置錯誤則返回錯誤代碼 0xad 0x11 0x11 0x11 0x65 0xa7
- send485[3]=0x11;
- crc=CRC16_2(send485,4);
- send485[4]=(unsigned char)(crc&0xff);
- send485[5]=(unsigned char)((crc&0xff00)>>8);
- RS485_Send_Data(send485,6); }
- else{RS485_Init(array[rsp]);
- flash[1]=10;
- flash[4]=rsp;
- //設(shè)置成功 返回 0xad 0x02 0x00 0x00 0x57 0x91
- send485[2]=0x00;
- send485[3]=0x00;
- crc=CRC16_2(send485,4);
- send485[4]=(unsigned char)(crc&0xff);
- send485[5]=(unsigned char)((crc&0xff00)>>8);
- RS485_Send_Data(send485,6);}
- break;
- case 0x03: //查詢NH4值
- send485[0]=0xad;
- send485[1]=0x03;
- crc=CRC16_2(send485,4);
- send485[4]=(unsigned char)(crc&0xff);
- send485[5]=(unsigned char)((crc&0xff00)>>8);
- RS485_Send_Data(send485,6);
- break;
- case 0x04: //校準(zhǔn)斜率
- switch(canget[2])
- {
- case 0x00:
-
- send485[0]=0xad;
- send485[1]=0x04;
- crc=CRC16_2(send485,4);
- send485[4]=(unsigned char)(crc&0xff);
- send485[5]=(unsigned char)((crc&0xff00)>>8);
- RS485_Send_Data(send485,6);
- }
- }
- }
- Can_Receive_Msg(canget);
- if (canget[0]==0xad)
- {
- switch (canget[1])
- {
-
- case 0x02: //設(shè)置can頻率
- canbuf[0]=0xad;
- canbuf[1]=0x02;
- phase=(int)canget[3]+(int)(256*canget[2]);
- if(2000%phase!=0) {canbuf[2]=0x11; //如頻率設(shè)置錯誤則返回錯誤代碼 0xad 0x11 0x11 0x11 0x65 0xa7
- canbuf[3]=0x11;
- crc=CRC16_2(canbuf,4);
- canbuf[4]=(unsigned char)(crc&0xff);
- canbuf[5]=(unsigned char)((crc&0xff00)>>8);
- Can_Send_Msg(canbuf,6); }
- else{brq=(u16)(2000/phase);
- flash[0]=10;
- flash[3]=brq;
- STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)flash,10);
- CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,brq,CAN_Mode_Normal);//設(shè)置成功 返回 0xad 0x02 0x00 0x00 0x57 0x91
- canbuf[2]=0x00;
- canbuf[3]=0x00;
- crc=CRC16_2(canbuf,4);
- canbuf[4]=(unsigned char)(crc&0xff);
- canbuf[5]=(unsigned char)((crc&0xff00)>>8);
- Can_Send_Msg(canbuf,6);}
- break;
- case 0x03: //查詢NH4值
- canbuf[0]=0xad;
- canbuf[1]=0x03;
- crc=CRC16_2(canbuf,4);
- canbuf[4]=(unsigned char)(crc&0xff);
- canbuf[5]=(unsigned char)((crc&0xff00)>>8);
- Can_Send_Msg(canbuf,6);
- break;
- case 0x04: //校準(zhǔn)斜率
- switch(canget[2])
- {
- case 0x00:
-
- canbuf[0]=0xad;
- canbuf[1]=0x04;
- crc=CRC16_2(canbuf,4);
- canbuf[4]=(unsigned char)(crc&0xff);
- canbuf[5]=(unsigned char)((crc&0xff00)>>8);
- Can_Send_Msg(canbuf,6);
- }
- }
- }
- delay_ms(250);
-
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
硬件.rar
(626.83 KB, 下載次數(shù): 69)
2019-6-25 17:06 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
軟件.7z
(204.04 KB, 下載次數(shù): 49)
2019-6-25 22:03 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|