ネチズンによって投稿されたこの記事は、ウェブマスターはハードウェアを理解していない。
著者:陳明達
オリジナルタイトル:MCU入門第二レッスン--照明マスター
原文へのリンク:https//www.cnblogs.com/1996-Chinese-Chen/p/16814553.html
はじめに
前回のブログでは、マイクロコントローラの学習の道を正式に開始しました。マイクロコントローラの概念と、私たちが使用しているESP32シリーズマイクロコントローラのIOピン、GPIOとは何か、関連するバス通信の概念(UART、IIC、SPI)、パルス変調の概念(PWM)、および信号デジタル相互変換(ADCとDAC)、ボードの機能のいくつかを説明しました。今日のブログでは、正式に制御ハードウェアの最初のレッスンにお連れします。
どのMCUであっても、最初のレッスンはLEDライトを点灯させることです、一般的に“照明マスター”として知られています、ハハ、私たちの最初のレッスンも点灯され、私はグループにいて、誰もがLEDを購入することができませんでした、私たちは実際にコードを使用してLEDランプの1つを制御することができるので、電源がオンになった後に電源ライト、赤いライトが点灯し、電源が正常になりますが、同時に青のライトがありますが、デフォルトでは表示されません。次に、ESP32開発ボードの別のLEDライトを点滅させます。

ライトアップ。
void setup() {
// put your setup code here, to run once:
pinMode(2,OUTPUT);
}
void loop() {
digitalWrite(2, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(2, LOW); // sets the LED off
delay(1000);
}
最初のコードは、上記のように、ボード上の別の青いライトを点灯することができます、最初にコードについて話し、上記のセットアップ、シングルチップ電源は、一度だけ実行されます、つまり、各電源が一度、一度実行され、次のループは、コードのループであり、電源オン中、ループ、最初に実行されたセットアップ、上記のセットアップは、名前が示すように、シングルチップにいくつかの設定を行うために使用され、上記の設定は、出力のための2番目のピンを設定することです。つまり、シングルチップはピン2に出力され、出力と低レベルはLEDライトを点灯させるために使用されます。ESP32では、青色ランプはピン2なので、ここでは出力モードとしてピン2を設定します。
2番目のループコードは、最初の行はdigitalWriteメソッドを呼び出し、このメソッドは、特定のピンスイッチを与えるために、指定したピンにローレベルを書き込むことです。これは、ピン値を書き込むための最初のパラメータです。つまり、ピン値、2番目のパラメータは、値を書き込む必要がある値、HIGH、LOW、HIGH、LOWの2つ目のレベル、HIGH、LOWの電源、LOW、LOW、コードの2行目は、遅延関数で、値はミリ秒値、1000、1秒の休憩を取る。
下のGIFは、この実験の結果を示しています。青いライトが点滅し続けています。

コードコンパイルと書き込み。
コードを書いた後コンパイルしてMCUに書き込む必要があります書き終えるたびにエディタの左上隅にチェックマークボタンがありますこのボタンをクリックするとIDEがコードをコンパイルし始めますコンパイル後コードをMCUに書き込む必要がありますチェックマークの横にある右矢印ボタンをクリックするとコードが書き込みを開始します接続が表示されるのを待ちますMCUをダウンロードモードにしますシングルチップチップは2つのボタンを持っており、電源ランプはボタンを持っており、横レベルの横にボタンがあり、接続が表示されたときにボタンを離さずに下の矢印を押し続ける必要があり、プログラムが書き込まれます。



Arduino
Arduinoのための私たちの開発IDEは、私は以前、純粋なC言語を使用してESP32マイクロコントローラを開発するために純粋なC言語を使用し、Arduinoを使用しました。これは純粋なCよりも簡単で、入門に適していますが、C開発のために、原理は同じですが、違いで純粋に書かれています。
プログラムの実行では、ループコードでノンストップですが、メソッドの1つはメインメソッドであり、他のループは構文の違いであり、ArduinoはCとC++に基づいており、パッケージは高水準言語に近く、ここではArduinoのメソッドや定数、データ型などのいくつかを示しています。


C言語の使用
そして、C言語については、いくつかの基礎が良くない、またはC言語を深く使用していない、いくつかの困難があります、私はここに私が書いた赤外線制御スマートカーコードを投稿し、ここではesp32ネイティブCファイルを使用して開発し、その複雑さとArduinoに比べてまだわずかに複雑です。
/* brushed dc motor control example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* This example will show you how to use MCPWM module to control brushed dc motor.
* This code is tested with L298 motor driver.
* User may need to make changes according to the motor driver they use.
*/
#include <stdio.h>
#include "sdkconfig.h"
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_attr.h"
#include "driver/rmt.h"
#include "driver/mcpwm.h"
#include "soc/mcpwm_periph.h"
#include "IR_Rev.h"
// const static char *TAG = "IR_Rre Demo";
#define RECV_PIN 23 // 一体化红外接收头GPIO
uint8_t command = 0; // 接收到的ENC红外指令
int direction = 0;
float currentspeed = 0;
int currentcolor = 2;
#define GPIO_PWM0A_OUT 15 // Set GPIO 15 as PWM0A
#define GPIO_PWM0B_OUT 16 // Set GPIO 16 as PWM0B
#define GPIO_PWM1A_OUT 17
#define GPIO_PWM1B_OUT 18
#define GPIO_PWM2A_OUT 12 // Set GPIO 15 as PWM0A
#define GPIO_PWM2B_OUT 14 // Set GPIO 16 as PWM0B
#define GPIO_PWM3A_OUT 25
#define GPIO_PWM3B_OUT 26
#define RED 2
#define GREEN 4
#define BLUE 5
#define INFARE 21
static void mcpwm_example_gpio_initialize(void)
{
printf("initializing mcpwm gpio...\n");
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1A, GPIO_PWM1A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1B, GPIO_PWM1B_OUT);
mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM0A, GPIO_PWM2A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM0B, GPIO_PWM2B_OUT);
mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM1A, GPIO_PWM3A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM1B, GPIO_PWM3B_OUT);
}
// forwards he forward 替换实现顺时针吹风和逆时针吹风
/**
* @brief motor moves in forward direction, with duty cycle = duty %
*/
static void brushed_motor_forward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, float duty_cycle)
{
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A);
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_B, duty_cycle);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_DUTY_MODE_0); // call this each time, if operator was previously in low/high state
}
static void brushed_motor_forwards(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, float duty_cycle)
{
ESP_ERROR_CHECK(mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B));
ESP_ERROR_CHECK(mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_A, duty_cycle));
ESP_ERROR_CHECK(mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_DUTY_MODE_0)); // call this each time, if operator was previously in low/high state
}
// forwards he forward 替换实现顺时针吹风和逆时针吹风
/**
* @brief motor moves in forward direction, with duty cycle = duty %
*/
static void brushed_motor_backward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, float duty_cycle)
{
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B);
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_A, duty_cycle);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_DUTY_MODE_0); // call this each time, if operator was previously in low/high state
}
static void brushed_motor_backwards(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, float duty_cycle)
{
ESP_ERROR_CHECK(mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A));
ESP_ERROR_CHECK(mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_B, duty_cycle));
ESP_ERROR_CHECK(mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_DUTY_MODE_0)); // call this each time, if operator was previously in low/high state
}
/**
* @brief motor stop
*/
static void brushed_motor_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
{
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A);
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B);
}
static void setspeed(uint8_t command)
{
if ((uint8_t)command == 22)
{
printf("%d\n", 22);
currentspeed = 10;
}
else if ((uint8_t)command == 12)
{
printf("%d\n", 12);
currentspeed = 20;
}
else if ((uint8_t)command == 24)
{
printf("%d\n", 24);
currentspeed = 30;
}
else if ((uint8_t)command == 94)
{
printf("%d\n", 94);
currentspeed = 40;
}
else if ((uint8_t)command == 8)
{
printf("%d\n", 8);
currentspeed = 50;
}
else if ((uint8_t)command == 28)
{
printf("%d\n", 28);
currentspeed = 60;
}
else if ((uint8_t)command == 90)
{
printf("%d\n", 90);
currentspeed = 70;
}
else if ((uint8_t)command == 66)
{
printf("%d\n", 66);
currentspeed = 80;
}
else if ((uint8_t)command == 82)
{
printf("%d\n", 82);
currentspeed = 90;
}
else if ((uint8_t)command == 74)
{
printf("%d\n", 74);
currentspeed = 100;
}
}
static void head(float speed)
{
brushed_motor_forward(MCPWM_UNIT_0, MCPWM_TIMER_0, speed);
brushed_motor_forwards(MCPWM_UNIT_0, MCPWM_TIMER_1, speed);
brushed_motor_forward(MCPWM_UNIT_1, MCPWM_TIMER_0, speed);
brushed_motor_forwards(MCPWM_UNIT_1, MCPWM_TIMER_1, speed);
}
static void last(float speed)
{
brushed_motor_backward(MCPWM_UNIT_0, MCPWM_TIMER_0, speed);
brushed_motor_backwards(MCPWM_UNIT_0, MCPWM_TIMER_1, speed);
brushed_motor_backward(MCPWM_UNIT_1, MCPWM_TIMER_0, speed);
brushed_motor_backwards(MCPWM_UNIT_1, MCPWM_TIMER_1, speed);
}
static void left(float speed)
{
mcpwm_set_signal_low(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_OPR_A);
mcpwm_set_signal_low(MCPWM_UNIT_1, MCPWM_TIMER_0, MCPWM_OPR_B);
}
static void right(float speed)
{
mcpwm_set_signal_low(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B);
mcpwm_set_signal_low(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A);
}
/**
* @brief Configure MCPWM module for brushed dc motor
*/
static void mcpwm_example_brushed_motor_control(void *arg)
{
// 1. mcpwm gpio initialization
mcpwm_example_gpio_initialize();
// 2. initial mcpwm configuration
printf("Configuring Initial Parameters of mcpwm...\n");
mcpwm_config_t pwm_config;
pwm_config.frequency = 1000; // frequency = 500Hz,
pwm_config.cmpr_a = 0; // duty cycle of PWMxA = 0
pwm_config.cmpr_b = 0; // duty cycle of PWMxb = 0
pwm_config.counter_mode = MCPWM_UP_COUNTER;
pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config)); // Configure PWM0A & PWM0B with above settings
mcpwm_config_t pwm_configs;
pwm_configs.frequency = 1000; // frequency = 500Hz,
pwm_configs.cmpr_a = 0; // duty cycle of PWMxA = 0
pwm_configs.cmpr_b = 0; // duty cycle of PWMxb = 0
pwm_configs.counter_mode = MCPWM_UP_COUNTER;
pwm_configs.duty_mode = MCPWM_DUTY_MODE_0;
ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_configs)); // Configure PWM0A & PWM0B with above settings
mcpwm_config_t pwm_configA;
pwm_configA.frequency = 1000; // frequency = 500Hz,
pwm_configA.cmpr_a = 0; // duty cycle of PWMxA = 0
pwm_configA.cmpr_b = 0; // duty cycle of PWMxb = 0
pwm_configA.counter_mode = MCPWM_UP_COUNTER;
pwm_configA.duty_mode = MCPWM_DUTY_MODE_0;
ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_0, &pwm_configA)); // Configure PWM0A & PWM0B with above settings
mcpwm_config_t pwm_configAs;
pwm_configAs.frequency = 1000; // frequency = 500Hz,
pwm_configAs.cmpr_a = 0; // duty cycle of PWMxA = 0
pwm_configAs.cmpr_b = 0; // duty cycle of PWMxb = 0
pwm_configAs.counter_mode = MCPWM_UP_COUNTER;
pwm_configAs.duty_mode = MCPWM_DUTY_MODE_0;
ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_0, &pwm_configAs)); // Configure PWM0A & PWM0B with above settings */ */
while (1)
{
command = IRrecvReadIR();
printf("IR Command is %02X\n", command);
printf("IR 111 is %d\n", (uint8_t)command);
if ((uint8_t)command == 69)
{
brushed_motor_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
brushed_motor_stop(MCPWM_UNIT_0, MCPWM_TIMER_1);
brushed_motor_stop(MCPWM_UNIT_1, MCPWM_TIMER_0);
brushed_motor_stop(MCPWM_UNIT_1, MCPWM_TIMER_1);
}
else if ((uint8_t)command == 64)
{
direction = 64;
head(currentspeed);
}
else if ((uint8_t)command == 25)
{
direction = 25;
last(currentspeed);
}
else if ((uint8_t)command == 7)
{
printf("IR 32 is %d\n", (uint8_t)command);
left(currentspeed);
}
else if ((uint8_t)command == 9)
{
printf("IR 23 is %d\n", (uint8_t)command);
right(currentspeed);
}
else
{
printf(" %d\n", direction);
setspeed(command);
if (direction == 64)
{
head(currentspeed);
}
else if (direction == 25)
{
last(currentspeed);
}
}
}
}
static void openlight(void *arg)
{
gpio_set_level(INFARE, 1);
while (1)
{
gpio_set_level(currentcolor, 1);
vTaskDelay(200 / portTICK_PERIOD_MS);
gpio_set_level(currentcolor, 0);
if(currentcolor==2)
{
currentcolor=4;
}
else if (currentcolor==4)
{
currentcolor=5;
}
else if (currentcolor==5)
{
currentcolor=2;
}
}
}
void app_main(void)
{
IRrecvInit(RECV_PIN, 3);
gpio_set_direction(INFARE, GPIO_MODE_OUTPUT);
gpio_set_direction(RED, GPIO_MODE_OUTPUT);
gpio_set_direction(GREEN, GPIO_MODE_OUTPUT);
gpio_set_direction(BLUE, GPIO_MODE_OUTPUT);
xTaskCreate(mcpwm_example_brushed_motor_control, "mcpwm_examlpe_brushed_motor_control", 4096, NULL, 5, NULL);
xTaskCreate(openlight, "openlight", 4096, NULL, 5, NULL);
}
そして、私のArduinoの好きな点は、いくつかのサードパーティ製ライブラリを使用する必要があるとき、VSCよりもここで拡張機能はいくつかを見つけるのが簡単です、プラグイン市場でCの言葉は見つけることができない可能性があり、オンラインで検索する必要があり、C言語で書かれた良いファイルを見つけ、インクルードが入ってきて使用し、赤外線のために少し難しいことを見つけるために、最後に私は長い時間をオンラインで見つけました。Arduinoでは、管理ライブラリインターフェイスで探しているライブラリやキーワードを検索するだけで、emmm、nugetのように簡単だと思います。
ここでは、キーワード、タイプに応じてサードパーティ製ライブラリを検索することができ、非常に便利ですが、サードパーティ製ライブラリのいくつかは、一般的に、簡単な入門として、直接使用することができる例があります、Arduinoはまだ非常に良い選択肢です。


おわりにまとめ
さて、今日の照明の最初のレッスンはここに来て、理解していない場合は、いつでも私に尋ねることができます、一緒にMCUを学ぶためにこのグループを追加することができ、その後、コースのstm 32シリーズを開き、IDEはブログのダウンロードアドレスを見ることができますBaiduネットワークディスクのアドレスですが、グループファイルもあります、ダウンロードする必要性があります、チュートリアルの私たちのシリーズは、自分自身がスマートカーを作ることができるまで出てきます。
