HC_SR04 Ultrasound Module and CC2530 Program

Posted by dmayo2 on Thu, 22 Aug 2019 13:52:28 +0200

objective

1. Using HC_SR04 to collect distance information
 2. The collected distance information is processed by CC2530 and sent to the computer through serial port.
3. View the collected distance information through serial debugging assistant

HC_SR04 Ultrasound Module

Brief Introduction to Modules

HC-SR04 ultrasonic ranging module can provide 2 cm-400 cm non-contact distance sensing function, ranging accuracy can reach up to 3 mm; the module includes ultrasonic transmitter, receiver and control circuit.

Basic working principle

(1) Trigger ranging with IO port TRIG, and submit a high-level message to a minimum of 10us.
(2) The module automatically sends 8 40 kHz square waves, and automatically detects whether there is a return signal. 
(3) Signal return, through the IO port ECHO output a high level, the duration of high level is the time of ultrasound from launch to return. Test distance= (high level time * sound speed (340M/S)/2;

Procedural section

#include<iocc2530.h>
#include<string.h>
#Define ECHO P_0//ECHO pin connection at P_0 pin
#Define TRIG P2_0//TRIG pins connected to P2_0 pins
unsigned int count_Time;        //Used to store count values
float  distance;                //Storage distance value
unsigned char count_TimeH;      //Used to store high count values
unsigned char count_TimeL;      //Used to store low count values
char buf[10];                   //Store serial port to send data
/*Delay 1us function*/
void delay_1us(int m){
  while(m--){
  asm("NOP");
  asm("NOP");
  asm("NOP");
  }
}
/*Delay 1ms function*/
void delayms(unsigned int ms)
{
  unsigned int i, j;
  for(i = ms; i > 0; i--)
    for(j = 1774; j > 0; j--);
}
/*Clock initialization*/
void clk_Init(){
   CLKCONCMD &= ~0X40;          //Setting the System Clock Source to 32MHZ Crystal Oscillator
   while(CLKCONSTA & 0x40);     //Waiting for Crystal Vibration Stability   
   CLKCONCMD &= ~0x3f;          //Set the main clock of the system to 32 MHZ, the output of timer marker to 32 MHZ, and the clock speed to 32 MHZ.         
}
/*Serial port initialization*/
void usart_Init(){
  PERCFG &= ~0x01;               //USART0 Standby Position 1
  P0SEL |= 0x0c;                 //P_2-P_3 as peripheral device
  P2DIR &= ~0xc0;                //Port 0 Peripheral Priority Configuration
  U0CSR |= 0X80;                 //Set to UART mode
  U0GCR |= 11;                   //Setting baud rate to 115200
  U0BAUD |= 216;
  UTX0IF = 0;
}
/*I/O Initialization*/
void io_Init(){
P2SEL &= ~0x01;                //P2_0 as a general I/O, output port
P2DIR |= 0X01;
P0SEL &= ~0x01;                //P_0 as general I/O, input port
P0DIR &= ~0X01;
P0IEN |= 0x01;                 //Open P_0 External Interrupt
PICTL |= 0x01;                 //P0 drop edge interruption
}
/*Timer 1 initialization*/
void timer1_Init(){
  T1CTL &= ~0x03;              //Stop running
  T1CTL |= 0X0c;               //Set to 128 minutes
  T1CNTH = 0;
  T1CNTL = 0;
}
/*HC_RS04 Initialization*/
void hc_sr04_Init(){
  TRIG = 1;
  delay_1us(20);
  TRIG = 0;
  while(!ECHO);
  T1CTL |= 0x01;                      //Start Free Running Mode
}
/*Serial Port Sender Function*/
void send(char *s){
  while(*s!='\0'){
  	U0DBUF= *s++;
 	while(UTX0IF == 0);               //Waiting for flag position 1, when 1, indicates that the current byte has been sent out.
    UTX0IF = 0; 
  }
}
/*P0 Port interruption*/
#pragma vector = P0INT_VECTOR
__interrupt void P0_isr(){
  if(P0IFG&0x01){                    //Judging whether it is P_0 interruption
	  T1CTL &= ~0x03;                //Stop T1 operation
	  P0IF = 0;                      //Clear port 0 interrupt flag
	  P0IFG &= ~0x01;                //Clear P_0 interrupt status flag
	  count_TimeH = T1CNTH;          //Remove the high bit of timer 1 counter
	  count_TimeL = T1CNTL;          //Take out the low bit of timer 1 counter
  }
}

int main(){
  clk_Init();
  usart_Init();
  EA = 1;                         //Open total interruption
  P0IE = 1;                       //Allow P0 port interrupt
  P0IF = 0;                       //Clear port 0 interrupt flag
  P0IFG &= ~0x01;                 //Clear P_0 interrupt status flag
  while(1){
	  timer1_Init();                  //timer initiated
	  hc_sr04_Init();                 //HC_SR04 initialization
	  delayms(60);
	  count_Time = count_TimeH*256+count_TimeL;//Calculate the Count Value of Timer 1
	  distance = count_Time*0.068;             //Calculating distance
	  /*Convert floating-point numbers to strings for easy transmission (only two decimal digits are retained here)*/
	  buf[0] = (unsigned int)distance/100+48;
	  buf[1] = (unsigned int)distance%100/10+48;
	  buf[2] = (unsigned int)distance%10+48;
	  buf[3] = '.';
	  buf[4] = (unsigned int)(distance*10)%10+48;
	  buf[5] = (unsigned int)(distance*100)%10+48;
	  buf[6] = '\n';
	  send(buf);
	  memset(buf,0,10);						  //Clean up arrays
  }
}


summary

1. The sensitivity of HC_SR04 is limited. When the distance is too small or too large, there will be data acquisition errors.
2. Each counting time = frequency dividing coefficient / timer marking output clock value, where the unit is us
Note: The output clock value marked by timer is the clock value set by CLKCONCMD.TICKSPD[2:0]. The default value is 16MHZ.
The frequency dividing coefficient is the value set by T1CTL.DIV[1:0]. The default is 1 frequency dividing.
3. Distance = counting value x, time x 0.017 per counting, unit cm calculated here
4. The interval of each acquisition can be adjusted appropriately.
If there are any mistakes, please correct them.

Reference material:

CC2530 Official Data Manual
 HC_SR04 Official Data Manual