近日,泥浆压力信号数据采集系统方案完成,采集频率设置为100Hz,每分钟收集一次,每次收集5次s,需要设计上下机之间的通信协议(比较简单,不喷)。上位机采用java因为语言是对的java比较熟悉。开始从淘宝买收集板,自己写上位机软件(用jfreechart),使用轮询(上位机发送命令读取当前数据),不到100Hz串口通信速率和稳定性的限制可能导致采集频率。因此,改变方案,采用先快速采集缓存在单片机中,再发送到上位机的方式,相对完成。
此次任务。主要协议是:上位机发送采集命令,单片机开始采集5秒,频率为100Hz,先缓存,上位机一直监控串口,有数据就收。通过状态变量workingModal详见程序。传感器输出4-20ma信号通过变送器转换为0-5V信号。下控制器和采集器STC12C5A60S2。
这次尝试仍涉及更多的知识,主要涉及java串口通信,javaGUI编写,jfreechart绘图、上下位机通信协议(这一点尤为重要,需要良好的设计才能简单实用),
单片机(主要是STC单片机)定时器,ADC、UART系统方案设计的使用(根据要求自行完成方案,实现方法是什么,需要什么硬件软件支持,每个方案的优缺点是
适用条件是什么?FT245BL的USB通信方案。
在这个过程中,最重要的问题是串口中断接收不完全,下位机传输
主要代码贴出,有意者读。详见我的126.com云盘中的java自己写的例子。
public class SerialConnection implements SerialPortEventListener,
CommPortOwnershipListener { private static Logger logger = Logger.getLogger(SerialConnection.class); private DataAcquisitionFrame parent; private SerialParameters parameters; private OutputStream os; private InputStream is; private CommPortIdentifier portId; private SerialPort sPort; int datalen = 2; private int[] readBuffer = new int[datalen];///这个缓冲数组为线程保存串口数据 int bytesNum = 0; private int sampleLen = 0 ;///目前收集了多少数据? //工作模式 private static final int MODAL_SAMPLING = 0; //0意味着收集真的开始了 private static final int MODAL_BEGINING = 1; //1表示开始收集数据 private static final int MODAL_SAMPLE_CONFIG = 2; //2表示采样率设置 private static final int MODAL_TIME_SETTING = 3; //3表示采样时间设置 private static final int MODAL_BAUD_SETTING = 4; //4表示波特率设置 private static final int MODAL_IDLE = 10; //10表示波特率设置 private int workingModal = SerialConnection.MODAL_IDLE; private int data = 0; public SerialConnection(DataAcquisitionFrame parent, SerialParameters parameters) { this.parent = parent; this.parameters = parameters; } public void openConnection() throws SerialConnectionException { // Obtain a CommPortIdentifier object for the port you want to open. try { portId = CommPortIdentifier.getPortIdentifier(parameters.getPortName()); } catch (NoSuchPortException e) { throw new SerialConnectionException(e.getMessage()); } // Open the port represented by the CommPortIdentifier object. Give // the open call a relatively long timeout of 30 seconds to allow // a different application to reliquish the port if the user // wnts to. try { sPort = (SerialPort)portId.open("SerialDemo", 3000); } catch (PortInUseException e) { throw new SerialConnectionException(e.getMessage()); } // Set the parameters of the connection. If they won't set, close the // port before throwing an exception. try { setConnectionParameters(); } catch (SerialConnectionException e) { sPort.close(); throw e; } // Open the input and output streams for the connection. If they won't // open, close the port before throwing an exception. try { os = sPort.getOutputStream(); is = sPort.getInputStream(); } catch (IOException e) { sPort.close(); throw new SerialConnectionException("Error opening i/o streams"); } // Add this object as an event listener for the serial port. try { sPort.addEventListener(this); } catch (TooManyListenersException e) { sPort.close(); throw new SerialConnectionException("too many listeners added"); } // Set notifyOnDataAvailable to true to allow event driven input. sPort.notifyOnDataAvailable(true); // Set notifyOnBreakInterrup to allow event driven break handling. sPort.notifyOnBreakInterrupt(true); // Set receive timeout to allow breaking out of polling loop during // input handling. try { sPort.enableReceiveTimeout(30); } catch (UnsupportedCommOperationException e) { } // Add ownership listener to allow ownership event handling. portId.addPortOwnershipListener(this); // System.out.println(sPort.getReceiveThreshold()); // try { // if(!sPort.isReceiveThresholdEnabled()){ // sPort.enableReceiveThreshold(1); // } // } catch (UnsupportedCommOperationException e1) { // e1.printStackTrace(); // } logger.info("串口打开成功"); //在这个开启定时器进行定时发送命令采集 timer = new Timer(); timer.schedule(new TimerTask(){ @Override public void run() { } private void sendBeginCommand(){ //发出命令等待一会儿 byte[] outbuf = new byte[]{0x01,0x00,0x00,0x00,0x2A}; try { /************************************CRC校验先不做*************************************************/ os.write(outbuf);//串口写数据 os.flush(); } catch (IOException e) { e.printStackTrace(); } } public void setConnectionParameters() throws SerialConnectionException { // Save state of parameters before trying a set. int oldBaudRate = sPort.getBaudRate(); int oldDatabits = sPort.getDataBits(); int oldStopbits = sPort.getStopBits(); int oldParity = sPort.getParity(); int oldFlowControl = sPort.getFlowControlMode(); // Set connection parameters, if set fails return parameters object // to original state. try { sPort.setSerialPortParams(parameters.getBaudRate(), parameters.getDatabits(), parameters.getStopbits(), parameters.getParity()); } catch (UnsupportedCommOperationException e) { parameters.setBaudRate(oldBaudRate); parameters.setDatabits(oldDatabits); parameters.setStopbits(oldStopbits); parameters.setParity(oldParity); throw new SerialConnectionException("Unsupported parameter"); } // Set flow control. try { sPort.setFlowControlMode(parameters.getFlowControlIn() | parameters.getFlowControlOut()); } catch (UnsupportedCommOperationException e) { throw new SerialConnectionException("Unsupported flow control"); } } public void closeConnection() { // If port is alread closed just return. if (!isWorking) { return; } // Check to make sure sPort has reference to avoid a NPE. if (sPort != null) { try { // close the i/o streams. os.close(); is.close(); } catch (IOException e) { System.err.println(e); } // Close the port. sPort.close(); // Remove the ownership listener. portId.removePortOwnershipListener(this); } isWorking = false; clearBuffer(); sampleLen = 0; timer.cancel(); logger.info("串口关闭"); } public void sendBreak() { sPort.sendBreak(1000); } } catch (IOException e1) { e1.printStackTrace(); } } } } /** * 每次读取一个字节 * @throws IOException */ private boolean checkCRC(int len){ MiscCRC16 m = new MiscCRC16(); //m.calCRC16(readBuffer, len);//不同的命令的长度是不一样的 //m.calCRC16(msg, msglen) int crc = m.getValue(); //System.out.println(crc); return (crc==0); } private void parseYaliData() { //01 04 02 03 02 38 01 //开始解析... if(checkCRC(7)){//压力信号的7位 //************************两个字节合成一个int********************************* int value=0; value = readBuffer[3] & 0xff;//高字节 //System.out.println(Integer.toHexString(value)); value = (value<<8)|(readBuffer[4] & 0xff);//低字节 //System.out.println(Integer.toHexString(value)); //******************************************************************************* //可能要使用这个函数来构建,动态生成millsecond,以备保存和恢复数据Millisecond(int millisecond, int second, int minute, int hour,int day, int month, int year) Millisecond now = millSecond.nextMilliSecond(); //获取一下时间 double mA = 4+(double)value*(20-4)/1023;//获取mA值 DecimalFormat df = new DecimalFormat("0.00"); //mA = Double.parseDouble(df.format(mA)); //this.parent.getmA().add(now,mA);//mA这个就不要了,由巴特沃斯滤波器产生 //System.out.println(mA); //按照校验数据获取压力值 double yali = (parent.getValidateData()[1]-parent.getValidateData()[0])*mA/16 +(3*parent.getValidateData()[0]-parent.getValidateData()[1])/4; logger.info("得到新压力数据:"+yali); //this.parent.getSeries().add(now,Double.parseDouble(df.format(yali))); this.parent.getYali().add(now,yali+1); double filterData=this.dul.addOneMoreValueAndFilterDataOut(yali); this.parent.getFilterData().add(now,filterData); this.parent.updateStatisticsBackColor();//更新背景色 this.parent.updateStatusPanelColor(); this.statisticscurrent.setText(df.format(this.dul.getCurrentValue())); this.statisticsaverage.setText(df.format(this.dul.getAverageValue())); this.statisticsmax.setText(df.format(this.dul.getMaxBuffValue())); this.statisticsmin.setText(df.format(this.dul.getMinBuffValue())); } } private void writeData2File(String model, String message) {//有时间使用log4j // TODO Auto-generated method stub File f=null; OutputStream fos = null; if("out".equals(model)){ f= new File(System.getProperty("user.dir")+"\\messageout.txt"); } else f= new File(System.getProperty("user.dir")+"\\messagein.txt"); try { fos = new FileOutputStream(f,true); fos.write(message.getBytes()); fos.flush(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if(fos != null){ fos.close();} } catch (IOException e) { e.printStackTrace();} } } public void ownershipChange(int type) { if (type == CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED) { PortRequestedDialog prd = new PortRequestedDialog(parent); } } public boolean getWorking() { // TODO Auto-generated method stub return isWorking; } public void setWorking(boolean b) { this.isWorking = b; } }
下位机程序
#include "Commons.h" #include "UART.h" #include "Timer0.h" #include "ADC.h" void main() { int i=0; unsigned char sc = 100; //采样率的设置值sc赫兹 unsigned char ts = 5; //采样时间设置ts秒 unsigned char bs = 1; //波特率设置 1--2400 2--4800 4--9600 8--19200 16--38400 32--76800 P3M1 &= 0xEF; P3M0 |= 0x10; //把P3.4口设置为推挽输出 LEDMCUFAST(); //快闪表示正常工作 P0=0xFF; //端口配置为可读 Uart_init(); //串口中断,可以读写 Init_Timer0(); //定时器0初始化 InitADC(0); //ADC初始化,P1.0 while(1) //死循环等待串口送来数据处理 { /收到上位机传过来的数据,目前只能是半双工工作模式,也就是只能单接收或者单发送// //接收到上位机来的信息,开始采样?配置参数(采样率设置,采集时间设置,传输波特率设置)?/// if(IsReceived_UART()==1) //判断接收到了串口数据结束符 { ClrFlag_UART(); //清除标志位 /*回发数据握手 for(i=0;i<Return_Recv_Len();i++) //得到发送来的数据 { SendOneByte(Return_Rxbuffer_UART()[i]); //一个字节一个字节地往串口发送命令 }*/ //目前的协议是COMMAND(1字节)+DATA(1字节)+CRC16(2字节,前面命令和*的CRC16校验)+* if(Return_Rxbuffer_UART()[4] == '*') // && ((Return_Rxbuffer_UART()[2]<<8 | Return_Rxbuffer_UART()[3])==CalCRC16(Return_Rxbuffer_UART(),2))) //现在还没加入校验 { switch(Return_Rxbuffer_UART()[0]) { case 0x01: //接收到命令就开启定时器0,开始采样 01 00 03 70 2A { ClrBuffer_ADC(); //清空缓冲区 //这个还未验证,这句话是后加的 Start_Timer0(); StartADC(); SendOneByte('O'); //发送OK表示我要采集数据了 SendOneByte('K'); //4F 4B break; } case 0x02: //接收到02表示采样频率设置 02 64 01 3b 2A { sc = Return_Rxbuffer_UART()[1]; SendOneByte('S'); //发送SC表示Sampling Config SendOneByte('C'); //53 43 break; } case 0x03: //接收到03表示采样时间设置 03 05 c1 43 2A { ts = Return_Rxbuffer_UART()[1]; SendOneByte('T'); //发送TS表示Timing Setting SendOneByte('S'); //54 53 break; } case 0x04: //接收到04表示波特率设置 04 01 c2 b0 2A { bs = Return_Rxbuffer_UART()[1]; SendOneByte('B'); //发送BS表示Baud Setting SendOneByte('S'); //42 53 break; } default :{} } LEDMCUSLOW(); //慢闪指示收到串口数据 //花2s } ClrRxbuffer_UART(); //清缓冲区 } 如果ADC所有的采样完成了/ else if(IsFull_ADC()==1) //ADC所有的数据准备好 //总共花5s { ClrFlag_Timer0(); //清标记 Send2UART(); //发送结果 ClrBuffer_ADC(); //清空缓冲区 // LEDMCUFAST(); //快闪指示发送完成ADC数据 //花2s } } }
#include <STC12C5A60S2.h> sbit led=P3^4; unsigned int CalCRC16(unsigned char* msg, unsigned int msglen); void LEDMCUFAST(); void LEDMCUSLOW(); void ChangeLight(); void delay100us(); void delay1ms(); void delay(unsigned int xx);
#include "Commons.h" #include <intrins.h> //校验表,需要用8位的unsigned char来保存 /*加入这个校验之后好像单片机的运转就混乱了,校验一位(命令)还行 unsigned char code auchCRCHi[] = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; unsigned char code auchCRCLo[] = { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 }; unsigned int CalCRC16(unsigned char* msg, unsigned int msglen) //返回16位无符号整数 { unsigned char crcHigh = 0xFF; unsigned char crcLow = 0xFF; unsigned int i; unsigned char index; for (i = 0; i < msglen; i++) { index = (crcHigh & 0xFF) ^ (msg[i] & 0xFF); crcHigh = (crcLow & 0xFF) ^ (auchCRCHi[index] & 0xFF); crcLow = auchCRCLo[index] & 0xff; } return (crcHigh & 0xFF) << 8 | (crcLow & 0xFF); } //*/ void LEDMCUFAST() { unsigned char i; led=0; for(i=0;i<40;i++) { led=~led; delay(50); } } void LEDMCUSLOW() { unsigned char i; led=0; for(i=0;i<20;i++) { led=~led; delay(100); } } void ChangeLight() { led = ~led; } void delay100us() { unsigned int i=50; while(i--) { _nop_(); _nop_(); } } void delay1ms() { unsigned char i=10; while(i--) { delay100us(); } } void delay(unsigned int t) { unsigned int i; for(i=0;i<t;i++) { delay1ms(); } }
//CONST FOR ADC #define ADC_POWER 0x80 //ADC POWER CONTROL BIT #define ADC_FLAG 0x10 //ADC COMPLETE FLAG #define ADC_START 0x08 //ADC START CONTROL BIT #define ADC_SPEEDLL 0x00 //ADC COMPLETE 540 CLOCKS #define ADC_SPEEDL 0x20 //ADC COMPLETE 360 CLOCKS #define ADC_SPEEDH 0x40 //ADC COMPLETE 180 CLOCKS #define ADC_SPEEDHH 0x60 //ADC COMPLETE 90 CLOCKS void InitADC(unsigned char ch); void StartADC(); void CloseADC(); void WaitforRes(); unsigned int GetResADC(); //unsigned char CH = 0;//通道 /* void ADC_Power_On(); void Set_P12_ASF(); void Set_P12_Normal_IO(); void Set_ADC_Channel_2(); unsigned int Get_AD_Result(); void AD_initial(); */
#include "ADC.h" #include "Commons.h" // ADC INTERRUPUT SERVICE /* void adc_isr() interrupt 5 using 1 { ADC_CONTR &= !ADC_FLAG; //CLEAR ADC INTERRUPT FLAG //处理结果 //发送到上位机或者存储起来 //ADC_RES ADC_RESL SendOneByte(ADC_RES); //发送高8位 SendOneByte(ADC_RESL);//发送低2位 //切换通道吗? } */ /*ch = 0(P1.0),1(P1.1),2(P1.2),3(P1.3),4(P1.4),5(P1.5),6(P1.6),7(P1.7)*/ void InitADC(unsigned char ch) { P1ASF = 2^ch; //SET ch AS ANALOG INPUT PORT } void StartADC() //由定时器0每次中断中调用开启 { ADC_RES = 0; //清空结果 ADC_RESL = 0; ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START; //ADC开启转换 } void CloseADC() //关闭ADC { ADC_RES = 0; //清空结果 ADC_RESL = 0; ADC_CONTR &= !ADC_START; //ADC关闭 } void WaitforRes() { while((ADC_CONTR & ADC_FLAG) != ADC_FLAG) {delay1ms();} //一直等待ADC转换结束 ADC_CONTR &= !ADC_FLAG; //CLEAR ADC INTERRUPT FLAG } unsigned int GetResADC() { unsigned int res = 0; WaitforRes(); //这里有个重大发现,声明必须在函数开始 // res = (res | ADC_RES)<<8; //高八位 // res = (res | ADC_RESL); //低八位,实际上只有低两位 res = (res | 0xfd)<<8; //做测试用 res = (res | 0xde); return res; } /* void ADC_Power_On() { ADC_CONTR=ADC_CONTR||0x80; //开启电源 delay(1); } void Set_P12_ASF() { P1ASF=P1ASF||0x04;//#00000100B ,设置P1.2为模拟功能 } void Set_P12_Normal_IO() { P1ASF=P1ASF||0xfb;//#11111011B,设置P1.2为普通IO口 } void Set_ADC_Channel_2() { ADC_CONTR=0xe2;//#111000010B,设置P1.2为A/D转换通道 delay(1); } unsigned int Get_AD_Result() { unsigned int mm,kk=0x10; //#00010000 flag ADC_RES=0; ADC_CONTR=ADC_CONTR||0x08;//启动AD delay(4); mm=ADC_CONTR&&kk; while(!mm);//未完成等待 ADC_CONTR=ADC_CONTR & 0xe7;//#11100111B,清ADC_FLAG,ADC_START位,停止AD return(ADC_RES);//返回结果 } void AD_initial() { ADC_Power_On(); Set_P12_ASF(); Set_P12_Normal_IO(); Set_ADC_Channel_2(); } */
void Init_Timer0(); void Start_Timer0(); void Close_Timer0(); unsigned char IsFull_ADC(); void ClrFlag_Timer0(); unsigned int* Return_Buffer_ADC(); void ClrBuffer_ADC(); void Send2UART();
//中断中开启ADC开始采集,使采集的采样率为100HZ #include "Timer0.h" #include "Commons.h" #include "ADC.h" #include "UART.h" #define LEN_Timer0ADC_BUFFER 1000 //缓冲器长度,最多1000个字节:100HZ采5秒,就有500个数,1000个字节 unsigned char Buffer_Timer0ADC[LEN_Timer0ADC_BUFFER]; //ADC结果缓冲区 unsigned int Bufferpos_Timer0ADC=0; //接收缓冲区指针 unsigned char flag_ADC=0; //是否准备好所有的新数据,0没有,1有 /*(2^16-x)*12/(12*10^6) = 1/100*/ #define Reload_Value_T0H 0xD8 //定时器0H重装值 #define Reload_Value_T0L 0xF0 //定时器0L重装值 void Init_Timer0() { TMOD=0x21; //定时器1为8位自动重装计数器,用于产生波特率 ,定时器0为16位计数器 TR0=0; // ET0 = 1; //允许中断 ClrBuffer_ADC(); } void Start_Timer0() { TH0=Reload_Value_T0H; //设置初值 TL0=Reload_Value_T0L; TR0=1; //开启定时器 } void Close_Timer0() { TR0=0; //关闭定时器0 TH0=0; //清空初值 T