Showing posts with label Timer/Counter. Show all posts
Showing posts with label Timer/Counter. Show all posts

Thursday, December 28, 2023

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8

Overview

HC-SR04 is an ultrasonic range finder. It uses sound wave traveling to find detected object distance. Its working range is between 4cm and 4m. To control and get distance data from this sensor we can use a digital circuit, or a microprocessor, or even manually by hand. Its echo output is a logic high level TTL signal with a specific period. A microprocessor's timer is used for calculating the timing signal associated with distance. For more details about using this sensor with a simple PIC16F84A micro-controller you can see this post.

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
PIC16F887 Prototyping Board

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
PIC16F887 Prototyping Board
 
PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
HC-SR04 Module Front

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
HC-SR04 Module Back

MPLABX IDE and XC8 C Programming

In this XC8 programming example, I use a PIC16F887 8-bit micro-controller to read distance data, and displaying its timing value with calculated distance on a 16x4 character LCD. I use Timer0 timer/counter to measure the sensor's TTL high pulse period.

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
Schematic and Program Simulation

An 8MHz internal RC oscillator is used for the system. Timer0 prescaler is set to 1:2 to get a 1µs timing ticks. Since this timer module is an 8-bit timer/counter I use TIMER0 interrupt to expand its timing period. Hence it becomes a 16-bit timer with the aid of timing interrupt. 

An 8-bit micro-controller is easy to program using C in MPLABX IDE and XC8 embedded C compiler from Microchip Technology. An HD44780 character LCD is very simple to interface and program. This character LCD is common operate in 4-bit data transfer mode.

  1. /*
  2.  * File: main.c
  3.  * Author: Admin
  4.  *
  5.  * Created on December 28, 2023, 9:51 PM
  6.  */
  7.  
  8. #include <xc.h>
  9. #include "config.h"
  10. #include "lcd.h"
  11.  
  12. #include <stdio.h>
  13.  
  14. #define _XTAL_FREQ 8000000UL
  15.  
  16. #define TRIGGER RD6
  17. #define ECHO RD7
  18.  
  19. volatile uint8_t T0OV=0;
  20. volatile uint16_t myCounter=0;
  21. volatile uint16_t getDistance=0, temp=0;
  22.  
  23. void __interrupt() T0_ISR(){
  24. if(T0IF==1){
  25. T0OV+=1;
  26. myCounter++;
  27. T0IF=0;
  28. }
  29. }
  30.  
  31. void readDistance(void){
  32. char msg[8];
  33. TRIGGER=1;
  34. __delay_us(10);
  35. TRIGGER=0;
  36. __delay_us(30);
  37. while(ECHO==0){
  38. /*Waiting For High Pulse Response, Or Sensor Present*/
  39. temp++;
  40. __delay_us(10);
  41. if(temp>=20) break;
  42. }
  43. TMR0=0;
  44. T0OV=0;
  45. while(ECHO==1);
  46. temp=(T0OV<<8)+TMR0+14;
  47. getDistance=temp/58;
  48.  
  49. lcdXY(5,4);
  50. sprintf(msg,"%4d %cS ",temp,228);
  51. lcdString(msg);
  52. lcdXY(5,2);
  53. if(temp>=116&&getDistance<=400){
  54. sprintf(msg,"%3d",getDistance);
  55. lcdString(msg);
  56.  
  57. temp%=58;
  58. temp=(temp*100)/58;
  59. sprintf(msg,".%d%dcm",temp/10,temp%10);
  60. lcdString(msg);
  61. }else lcdString("Invalid");
  62. temp=0;
  63. T0OV=0;
  64. TMR0=0;
  65. }
  66.  
  67. void main(void) {
  68. /*8MHz internal oscillator*/
  69. OSCCONbits.IRCF=7;
  70. lcdInit();
  71. /*RD7 as input*/
  72. PORTD=0;
  73. TRISD=0x80;
  74. /*Select system clock*/
  75. T0CS=0;
  76. /*Timer0 Prescaler*/
  77. PSA=0;
  78. /*Select 1:2 Prescaler*/
  79. OPTION_REGbits.PS=0;
  80. /*Enable Timer0 Interrupt*/
  81. T0IE=1;
  82. GIE=1;
  83. T0IF=0;
  84.  
  85. lcdXY(5,1);
  86. lcdString("PIC16F887 ");
  87. lcdXY(1,2);
  88. lcdString("HC-SR04 Distance");
  89. lcdXY(2,3); lcdString("Sensor Example");
  90. lcdXY(2,4); lcdString("MPLABX IDE XC8");
  91. __delay_ms(2000);
  92. lcdCommand(0x0C);
  93. lcdCommand(0x01);
  94. __delay_ms(5);
  95. lcdXY(5,1);
  96. lcdString("Distance: ");
  97. lcdXY(1,3);
  98. lcdString("TIMER0 Duration:");
  99. TMR0=0;
  100. while(1){
  101. if(myCounter>=5000){
  102. readDistance();
  103. myCounter=0;
  104. }
  105. }
  106. return;
  107. }
  108.  
  109.  
  110.  

The Interrupt Service Routine (ISR) for PIC micro-controller in XC8 programming is differ depends on the version of the compiler. Some time the source codes can generate error in other version. In some case, it can be build but the ISR does not work during run-time. So we will need to read its compiler user manual. 

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
MPLABX IDE Dashboard

Click here to download its source file.




Monday, August 28, 2023

STM32F103C8T6 Blue Pill SysTick LED Blinking

Systick is timer that come with all of ARM Cortext-M3 micro-controllers. It's useful for creating a precise timing delay, time measurement, multi-tasking, etc.

In this example, I will use STM32 ARM SysTick to blink an LED. It's the built-in LED on STM32 Blue Pill module.

STM32F103C8T6 Blue Pill SysTick LED Blinking
Wiring Diagram







STM32CubeIDE Source Code:

  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file : main.c
  5.   * @brief : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   * opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22.  
  23. /* Private function prototypes -----------------------------------------------*/
  24. void SystemClock_Config(void);
  25. static void MX_GPIO_Init(void);
  26. /* USER CODE BEGIN PFP */
  27.  
  28. /* USER CODE END PFP */
  29.  
  30. /* Private user code ---------------------------------------------------------*/
  31. /* USER CODE BEGIN 0 */
  32.  
  33. /* USER CODE END 0 */
  34.  
  35. /**
  36.   * @brief The application entry point.
  37.   * @retval int
  38.   */
  39. int main(void)
  40. {
  41. /* USER CODE BEGIN 1 */
  42.  
  43. /* USER CODE END 1 */
  44.  
  45. /* MCU Configuration--------------------------------------------------------*/
  46.  
  47. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  48. HAL_Init();
  49.  
  50. /* USER CODE BEGIN Init */
  51.  
  52. /* USER CODE END Init */
  53.  
  54. /* Configure the system clock */
  55. SystemClock_Config();
  56.  
  57. /* USER CODE BEGIN SysInit */
  58.  
  59. /* USER CODE END SysInit */
  60.  
  61. /* Initialize all configured peripherals */
  62. MX_GPIO_Init();
  63.  
  64. /*SysTick Configuration*/
  65. SystemCoreClockUpdate();
  66. /*Generate interrupt for each 10 ms*/
  67. SysTick_Config(SystemCoreClock/100);
  68. SysTick ->CTRL = 0;
  69. SysTick ->VAL = 0;
  70. SysTick ->CTRL = (SysTick_CTRL_TICKINT_Msk
  71. |SysTick_CTRL_ENABLE_Msk
  72. |SysTick_CTRL_CLKSOURCE_Msk);
  73.  
  74. while (1)
  75. {
  76. /* USER CODE END WHILE */
  77.  
  78. /* USER CODE BEGIN 3 */
  79. }
  80. /* USER CODE END 3 */
  81. }
  82.  
  83. void SysTick_Handler(void)
  84. {
  85.  
  86. HAL_IncTick();
  87. /*Toggle PC13 for every 1 second*/
  88. if(uwTick>=100){
  89. HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
  90. uwTick=0;
  91. }
  92. }
  93.  
  94. /**
  95.   * @brief System Clock Configuration
  96.   * @retval None
  97.   */
  98. void SystemClock_Config(void)
  99. {
  100. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  101. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  102.  
  103. /** Initializes the RCC Oscillators according to the specified parameters
  104.   * in the RCC_OscInitTypeDef structure.
  105.   */
  106. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  107. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  108. RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  109. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  110. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  111. {
  112. Error_Handler();
  113. }
  114. /** Initializes the CPU, AHB and APB buses clocks
  115.   */
  116. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  117. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  118. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  119. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  120. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  121. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  122.  
  123. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  124. {
  125. Error_Handler();
  126. }
  127. }
  128.  
  129. /**
  130.   * @brief GPIO Initialization Function
  131.   * @param None
  132.   * @retval None
  133.   */
  134. static void MX_GPIO_Init(void)
  135. {
  136. GPIO_InitTypeDef GPIO_InitStruct = {0};
  137.  
  138. /* GPIO Ports Clock Enable */
  139. __HAL_RCC_GPIOC_CLK_ENABLE();
  140. __HAL_RCC_GPIOA_CLK_ENABLE();
  141.  
  142. /*Configure GPIO pin Output Level */
  143. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
  144.  
  145. /*Configure GPIO pin : PC13 */
  146. GPIO_InitStruct.Pin = GPIO_PIN_13;
  147. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  148. GPIO_InitStruct.Pull = GPIO_NOPULL;
  149. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  150. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  151.  
  152. }
  153.  
  154. /* USER CODE BEGIN 4 */
  155.  
  156. /* USER CODE END 4 */
  157.  
  158. /**
  159.   * @brief This function is executed in case of error occurrence.
  160.   * @retval None
  161.   */
  162. void Error_Handler(void)
  163. {
  164. /* USER CODE BEGIN Error_Handler_Debug */
  165. /* User can add his own implementation to report the HAL error return state */
  166. __disable_irq();
  167. while (1)
  168. {
  169. }
  170. /* USER CODE END Error_Handler_Debug */
  171. }
  172.  
  173. #ifdef USE_FULL_ASSERT
  174. /**
  175.   * @brief Reports the name of the source file and the source line number
  176.   * where the assert_param error has occurred.
  177.   * @param file: pointer to the source file name
  178.   * @param line: assert_param error line source number
  179.   * @retval None
  180.   */
  181. void assert_failed(uint8_t *file, uint32_t line)
  182. {
  183. /* USER CODE BEGIN 6 */
  184. /* User can add his own implementation to report the file name and line number,
  185.   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  186. /* USER CODE END 6 */
  187. }
  188. #endif /* USE_FULL_ASSERT */
  189.  
  190. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  191.  

 

Click here to download its source file. 

STM32F103C8T6 Blue Pill SysTick LED Blinking
Running Program on BreadBoard

 For other similar posts please check,

  1. Getting Started With STM32F103C8T6 Module with STM32CubeIDE
  2.  STM32F103C8T6 Blue Pill SysTick and Multiplexing Display Example
  3.  STM32F103C8T6 Blue Pill Switch And Multiplexing Display Interface Using SysTick
  4.  STM32F103C8T6 Blue Pill SysTick LED Blinking
  5. STM32F103R6 Shifts LEDs Using STM32CubeIDE 
  6. STM32F103R6 Common Anode Seven Segments Display Example 

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (56) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (47) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (71) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (3) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (31) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)