当前位置:文档之家› stm32驱动wifi_88W8686_WM-G-MR-09_edited

stm32驱动wifi_88W8686_WM-G-MR-09_edited

stm32驱动wifi_88W8686_WM-G-MR-09_edited
stm32驱动wifi_88W8686_WM-G-MR-09_edited

F:\WiFi_V2.1\src\wifi\wlan_scan.c

#include "wifi.h"

#include

#include

#include

/********************************************************

Local Constants

********************************************************/

//! Approximate amount of data needed to pass a scan result back to iwlist #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \

+ MRVDRV_MAX_SSID_LENGTH \

+ IW_EV_UINT_LEN \

+ IW_EV_FREQ_LEN \

+ IW_EV_QUAL_LEN \

+ MRVDRV_MAX_SSID_LENGTH \

+ IW_EV_PARAM_LEN \

+ 40) /* 40 for WPAIE */

//! Memory needed to store a max sized Channel List TLV for a firmware scan

#define CHAN_TLV_MAX_SIZE (sizeof(MrvlIEtypesHeader_t) \

+ (MRVDRV_MAX_CHANNELS_PER_SCAN \

* sizeof(ChanScanParamSet_t)))

//! Memory needed to store a max number/size SSID TLV for a firmware scan #define SSID_TLV_MAX_SIZE (1 * sizeof(MrvlIEtypes_SsIdParamSet_t))

//! WPS TLV MAX size is MAX IE size plus 2 bytes for u16 MRVL TLV extension #define WPS_TLV_MAX_SIZE (sizeof(IEEEtypes_VendorSpecific_t) + 2)

//! Maximum memory needed for a wlan_scan_cmd_config with all TLVs at max #define MAX_SCAN_CFG_ALLOC (sizeof(wlan_scan_cmd_config) \

+ sizeof(MrvlIEtypes_NumProbes_t) \

+ CHAN_TLV_MAX_SIZE \

+ SSID_TLV_MAX_SIZE \

+ WPS_TLV_MAX_SIZE)

//! The maximum number of channels the firmware can scan per command #define MRVDRV_MAX_CHANNELS_PER_SCAN 14

/**

* @brief Number of channels to scan per firmware scan command issuance. *

* Number restricted to prevent hitting the limit on the amount of scan data

* returned in a single firmware scan command.

*/

#define MRVDRV_CHANNELS_PER_SCAN_CMD 4

//! Macro to enable/disable SSID checking before storing a scan table #ifdef DISCARD_BAD_SSID

#define CHECK_SSID_IS_VALID(x) ssid_valid(&bssidEntry.Ssid)

Page: 1

F:\WiFi_V2.1\src\wifi\wlan_scan.c

#else

#define CHECK_SSID_IS_VALID(x) TRUE

#endif

/********************************************************

Local Variables and Types

********************************************************/

/**

* @brief Interally used to send a configured scan cmd between driver routines

*/

typedef union

{

wlan_scan_cmd_config config; //!< Scan configuration (variable length) u8 configAllocBuf[MAX_SCAN_CFG_ALLOC]; //!< Max allocated block

} wlan_scan_cmd_config_tlv;

/**

* @brief Check if a scanned network compatible with the driver settings *

* WEP WPA WPA2 ad-hoc encrypt Network

* enabled enabled enabled AES mode Privacy WPA WPA2 Compatible

* 0 0 0 0 NONE 0 0 0 yes No security

* 0 1 0 0 x 1x 1 x yes WPA

* 0 0 1 0 x 1x x 1 yes WPA2

* 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES

*

* 1 0 0 0 NONE 1 0 0 yes Static WEP

* 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP

*

*

* @param Adapter A pointer to wlan_adapter

* @param index Index in ScanTable to check against current driver settings * @param mode Network mode: Infrastructure or IBSS

*

* @return Index in ScanTable, or error code if negative

*/

static int

IsNetworkCompatible(wlan_adapter * Adapter, int index, int mode)

{

BSSDescriptor_t *pBSSDesc;

ENTER();

pBSSDesc = &Adapter->ScanTable[index];

/* Don't check for compatibility if roaming */

if ((Adapter->MediaConnectStatus == WlanMediaStateConnected)

&& (Adapter->InfrastructureMode == Wlan802_11Infrastructure)

&& (pBSSDesc->InfrastructureMode == Wlan802_11Infrastructure)) { LEAVE();

return index;

}

if (Adapter->wps.SessionEnable == TRUE) {

printf("Return success directly in WPS period\n");

LEAVE();

return index;

}

if (pBSSDesc->InfrastructureMode == mode) {

if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPDisabled

&& !Adapter->SecInfo.WPAEnabled

&& !Adapter->SecInfo.WPA2Enabled

&&pBSSDesc->wpaIE.VendHdr.ElementId != WPA_IE

&&pBSSDesc->rsnIE.IeeeHdr.ElementId != RSN_IE

&& !Adapter->AdhocAESEnabled

&&Adapter->SecInfo.EncryptionMode == CIPHER_NONE

Page: 2

F:\WiFi_V2.1\src\wifi\wlan_scan.c

&& !pBSSDesc->Privacy) {

/* no security */

LEAVE();

return index;

} else if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPEnabled

&& !Adapter->SecInfo.WPAEnabled

&& !Adapter->SecInfo.WPA2Enabled

&& !Adapter->AdhocAESEnabled &&pBSSDesc->Privacy) {

/* static WEP enabled */

LEAVE();

return index;

} else if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPDisabled

&&Adapter->SecInfo.WPAEnabled

&& !Adapter->SecInfo.WPA2Enabled

&& (pBSSDesc->wpaIE.VendHdr.ElementId == WPA_IE)

&& !Adapter->AdhocAESEnabled

/* Privacy bit may NOT be set in some APs like LinkSys WRT54G

&& pBSSDesc->Privacy */

) {

/* WPA enabled */

printf("IsNetworkCompatible() WPA: index=%d wpa_ie=%#x "

"wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode=%#x "

"privacy=%#x\n",

index,

pBSSDesc->wpaIE.VendHdr.ElementId,

pBSSDesc->rsnIE.IeeeHdr.ElementId,

(Adapter->SecInfo.WEPStatus ==

Wlan802_11WEPEnabled) ? "e" : "d",

(Adapter->SecInfo.WPAEnabled) ? "e" : "d",

(Adapter->SecInfo.WPA2Enabled) ? "e" : "d",

Adapter->SecInfo.EncryptionMode, pBSSDesc->Privacy);

LEAVE();

return index;

} else if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPDisabled && !Adapter->SecInfo.WPAEnabled

&&Adapter->SecInfo.WPA2Enabled

&& (pBSSDesc->rsnIE.IeeeHdr.ElementId == RSN_IE)

&& !Adapter->AdhocAESEnabled

/* Privacy bit may NOT be set in some APs like LinkSys WRT54G && pBSSDesc->Privacy */

) {

/* WPA2 enabled */

printf( "IsNetworkCompatible() WPA2: index=%d wpa_ie=%#x " "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode=%#x "

"privacy=%#x\n",

index,

pBSSDesc->wpaIE.VendHdr.ElementId,

pBSSDesc->rsnIE.IeeeHdr.ElementId,

(Adapter->SecInfo.WEPStatus ==

Wlan802_11WEPEnabled) ? "e" : "d",

(Adapter->SecInfo.WPAEnabled) ? "e" : "d",

(Adapter->SecInfo.WPA2Enabled) ? "e" : "d",

Adapter->SecInfo.EncryptionMode, pBSSDesc->Privacy);

LEAVE();

return index;

} else if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPDisabled && !Adapter->SecInfo.WPAEnabled

&& !Adapter->SecInfo.WPA2Enabled

&& (pBSSDesc->wpaIE.VendHdr.ElementId != WPA_IE)

&& (pBSSDesc->rsnIE.IeeeHdr.ElementId != RSN_IE)

&&Adapter->AdhocAESEnabled

&&Adapter->SecInfo.EncryptionMode == CIPHER_NONE

&&pBSSDesc->Privacy) {

/* Ad-hoc AES enabled */

LEAVE();

return index;

} else if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPDisabled

&& !Adapter->SecInfo.WPAEnabled

Page: 3

F:\WiFi_V2.1\src\wifi\wlan_scan.c

&& !Adapter->SecInfo.WPA2Enabled

&& (pBSSDesc->wpaIE.VendHdr.ElementId != WPA_IE)

&& (pBSSDesc->rsnIE.IeeeHdr.ElementId != RSN_IE)

&& !Adapter->AdhocAESEnabled

&&Adapter->SecInfo.EncryptionMode != CIPHER_NONE

&&pBSSDesc->Privacy) {

/* dynamic WEP enabled */

printf( "IsNetworkCompatible() dynamic WEP: index=%d "

"wpa_ie=%#x wpa2_ie=%#x EncMode=%#x privacy=%#x\n",

index,

pBSSDesc->wpaIE.VendHdr.ElementId,

pBSSDesc->rsnIE.IeeeHdr.ElementId,

Adapter->SecInfo.EncryptionMode, pBSSDesc->Privacy);

LEAVE();

return index;

}

/* security doesn't match */

printf( "IsNetworkCompatible() FAILED: index=%d wpa_ie=%#x "

"wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", index,

pBSSDesc->wpaIE.VendHdr.ElementId,

pBSSDesc->rsnIE.IeeeHdr.ElementId,

(Adapter->SecInfo.WEPStatus ==

Wlan802_11WEPEnabled) ? "e" : "d",

(Adapter->SecInfo.WPAEnabled) ? "e" : "d",

(Adapter->SecInfo.WPA2Enabled) ? "e" : "d",

Adapter->SecInfo.EncryptionMode, pBSSDesc->Privacy);

LEAVE();

return -ECONNREFUSED;

}

/* mode doesn't match */

LEAVE();

return -ENETUNREACH;

}

/**

* @brief This function validates a SSID as being able to be printed *

* @param pSsid SSID structure to validate

*

* @return TRUE or FALSE

*/

static BOOLEAN

ssid_valid(WLAN_802_11_SSID * pSsid)

{

int ssidIdx;

for (ssidIdx = 0; ssidIdx SsidLength; ssidIdx++) {

if (!isprint(pSsid->Ssid[ssidIdx])) {

return FALSE;

}

}

return TRUE;

}

/**

* @brief Post process the scan table after a new scan command has completed *

* Inspect each entry of the scan table and try to find an entry that * matches our current associated/joined network from the scan. If

* one is found, update the stored copy of the BSSDescriptor for our

* current network.

*

* Debug dump the current scan table contents if compiled accordingly. *

Page: 4

F:\WiFi_V2.1\src\wifi\wlan_scan.c

* @param priv A pointer to wlan_private structure

*

* @return void

*/

static void

wlan_scan_process_results(wlan_private * priv)

{

wlan_adapter *Adapter = priv->adapter;

int i;

//int foundCurrent;

//foundCurrent = FALSE;

if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {

Adapter->CurBssParams.BSSDescriptor.pBeaconBuf = NULL;

Adapter->CurBssParams.BSSDescriptor.beaconBufSize = 0;

Adapter->CurBssParams.BSSDescriptor.beaconBufSizeMax = 0;

i = FindSSIDInList(Adapter,

&Adapter->CurBssParams.BSSDescriptor.Ssid,

Adapter->CurBssParams.BSSDescriptor.MacAddress,

Adapter->InfrastructureMode);

if (i >= 0) {

printf("Found current ssid/bssid in list @ index #%d\n", i);

/* Make a copy of current BSSID descriptor */

memcpy(&Adapter->CurBssParams.BSSDescriptor,

&Adapter->ScanTable[i],

sizeof(Adapter->CurBssParams.BSSDescriptor));

}

}

for (i = 0; i NumInScanTable; i++) {

printf( "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, "

"RSSI[%03d], SSID[%s]\n",

i,

Adapter->ScanTable[i].MacAddress[0],

Adapter->ScanTable[i].MacAddress[1],

Adapter->ScanTable[i].MacAddress[2],

Adapter->ScanTable[i].MacAddress[3],

Adapter->ScanTable[i].MacAddress[4],

Adapter->ScanTable[i].MacAddress[5],

(s32) Adapter->ScanTable[i].Rssi,

Adapter->ScanTable[i].Ssid.Ssid);

}

}

/**

* @brief Create a channel list for the driver to scan based on region info *

* Use the driver region/band information to construct a comprehensive list * of channels to scan. This routine is used for any scan that is not * provided a specific channel list to scan.

*

* @param priv A pointer to wlan_private structure

* @param scanChanList Output parameter: Resulting channel list to scan * @param filteredScan Flag indicating whether or not a BSSID or SSID filter * is being sent in the command to firmware. Used to

* increase the number of channels sent in a scan

* command and to disable the firmware channel scan

* filter.

*

* @return void

*/

static void

wlan_scan_create_channel_list(wlan_private * priv,

ChanScanParamSet_t * scanChanList,

BOOLEAN filteredScan)

Page: 5

F:\WiFi_V2.1\src\wifi\wlan_scan.c

wlan_adapter *Adapter = priv->adapter;

REGION_CHANNEL *scanRegion;

CHANNEL_FREQ_POWER *cfp;

int rgnIdx;

int chanIdx;

int nextChan;

u8 scanType;

chanIdx = 0;

/* Set the default scan type to the user specified type, will later

* be changed to passive on a per channel basis if restricted by

* regulatory requirements (11d or 11h)

*/

scanType = Adapter->ScanType;

for (rgnIdx = 0; rgnIdx region_channel); rgnIdx++) {

if (wlan_get_state_11d(priv) == ENABLE_11D &&

Adapter->MediaConnectStatus != WlanMediaStateConnected) {

/* Scan all the supported chan for the first scan */

if (!Adapter->universal_channel[rgnIdx].Valid)

continue;

scanRegion = &Adapter->universal_channel[rgnIdx];

/* clear the parsed_region_chan for the first scan */

memset(&Adapter->parsed_region_chan, 0x00,

sizeof(Adapter->parsed_region_chan));

} else {

if (!Adapter->region_channel[rgnIdx].Valid)

continue;

scanRegion = &Adapter->region_channel[rgnIdx];

}

for (nextChan = 0;

nextChan NrCFP; nextChan++, chanIdx++) {

cfp = scanRegion->CFP + nextChan;

if (wlan_get_state_11d(priv) == ENABLE_11D) {

scanType =

wlan_get_scan_type_11d(cfp->Channel,

&Adapter->parsed_region_chan);

}

switch (scanRegion->Band) {

case BAND_B:

case BAND_G:

default:

scanChanList[chanIdx].RadioType = HostCmd_SCAN_RADIO_TYPE_BG;

break;

if (scanType == HostCmd_SCAN_TYPE_PASSIVE) {

scanChanList[chanIdx].MaxScanTime =

wlan_cpu_to_le16(Adapter->PassiveScanTime);

scanChanList[chanIdx].ChanScanMode.PassiveScan = TRUE;

} else {

scanChanList[chanIdx].MaxScanTime =

wlan_cpu_to_le16(Adapter->ActiveScanTime);

scanChanList[chanIdx].ChanScanMode.PassiveScan = FALSE;

}

scanChanList[chanIdx].ChanNumber = cfp->Channel;

if (filteredScan) {

scanChanList[chanIdx].MaxScanTime =

Page: 6

F:\WiFi_V2.1\src\wifi\wlan_scan.c

wlan_cpu_to_le16(Adapter->SpecificScanTime);

scanChanList[chanIdx].ChanScanMode.DisableChanFilt = TRUE;

}

}

}

}

static void

wlan_add_wps_probe_request_ie(wlan_private * priv, u8 ** ppTlvOut) {

wlan_adapter *Adapter = priv->adapter;

MrvlIEtypesHeader_t *tlv;

if (Adapter->wps.wpsIe.VendHdr.Len) {

tlv = (MrvlIEtypesHeader_t *) * ppTlvOut;

tlv->Type = wlan_cpu_to_le16(TLV_TYPE_WPS_ENROLLEE_PROBE_REQ_TLV);

tlv->Len = wlan_cpu_to_le16(Adapter->wps.wpsIe.VendHdr.Len);

*ppTlvOut += sizeof(MrvlIEtypesHeader_t);

memcpy(*ppTlvOut,

Adapter->wps.wpsIe.VendHdr.Oui,

Adapter->wps.wpsIe.VendHdr.Len);

*ppTlvOut += (Adapter->wps.wpsIe.VendHdr.Len

+ sizeof(MrvlIEtypesHeader_t));

}

}

/**

* @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds

*

* Application layer or other functions can invoke wlan_scan_networks * with a scan configuration supplied in a wlan_ioctl_user_scan_cfg struct.

* This structure is used as the basis of one or many wlan_scan_cmd_config * commands that are sent to the command processing module and sent to * firmware.

*

* Create a wlan_scan_cmd_config based on the following user supplied * parameters (if present):

* - SSID filter

* - BSSID filter

* - Number of Probes to be sent

* - Channel list

*

* If the SSID or BSSID filter is not present, disable/clear the filter. * If the number of probes is not set, use the adapter default setting * Qualify the channel

*

* @param priv A pointer to wlan_private structure

* @param pUserScanIn NULL or pointer to scan configuration parameters * @param pScanCfgOut Output parameter: Resulting scan configuration

* @param ppChanTlvOut Output parameter: Pointer to the start of the

* channel TLV portion of the output scan config

* @param pScanChanList Output parameter: Pointer to the resulting channel * list to scan

* @param pMaxChanPerScan Output parameter: Number of channels to scan for * each issuance of the firmware scan command

* @param pFilteredScan Output parameter: Flag indicating whether or not * a BSSID or SSID filter is being sent in the

* command to firmware. Used to increase the number

* of channels sent in a scan command and to

* disable the firmware channel scan filter.

* @param pScanCurrentOnly Output parameter: Flag indicating whether or not

* we are only scanning our current active channel

*

* @return void

*/

static void

wlan_scan_setup_scan_config(wlan_private * priv,

const wlan_ioctl_user_scan_cfg * pUserScanIn,

Page: 7

F:\WiFi_V2.1\src\wifi\wlan_scan.c

wlan_scan_cmd_config * pScanCfgOut,

MrvlIEtypes_ChanListParamSet_t ** ppChanTlvOut,

ChanScanParamSet_t * pScanChanList,

int *pMaxChanPerScan,

BOOLEAN * pFilteredScan,

BOOLEAN * pScanCurrentOnly)

{

wlan_adapter *Adapter = priv->adapter;

const u8 zeroMac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };

MrvlIEtypes_NumProbes_t *pNumProbesTlv;

u8 *pTlvPos;

u16 numProbes;

u16 ssidLen;

int chanIdx;

int scanType;

int scanDur;

int channel;

int radioType;

int ssidIdx;

BOOLEAN ssidFilter;

MrvlIEtypes_WildCardSsIdParamSet_t *pWildCardSsidTlv;

/* The tlvBufferLen is calculated for each scan command. The TLVs added * in this routine will be preserved since the routine that sends

* the command will append channelTLVs at *ppChanTlvOut. The difference * between the *ppChanTlvOut and the tlvBuffer start will be used

* to calculate the size of anything we add in this routine.

*/

pScanCfgOut->tlvBufferLen = 0;

/* Running tlv pointer. Assigned to ppChanTlvOut at end of function

* so later routines know where channels can be added to the command buf */

pTlvPos = pScanCfgOut->tlvBuffer;

/*

* Set the initial scan paramters for progressive scanning. If a specific * BSSID or SSID is used, the number of channels in the scan command

* will be increased to the absolute maximum

*/

*pMaxChanPerScan = MRVDRV_MAX_CHANNELS_PER_SCAN;

/* Initialize the scan as un-filtered; the flag is later set to

* TRUE below if a SSID or BSSID filter is sent in the command

*/

*pFilteredScan = FALSE;

/* Initialize the scan as not being only on the current channel. If

* the channel list is customized, only contains one channel, and

* is the active channel, this is set true and data flow is not halted. */

*pScanCurrentOnly = FALSE;

if (pUserScanIn) {

/* Default the ssidFilter flag to TRUE, set false under certain

* wildcard conditions and qualified by the existence of an SSID

* list before marking the scan as filtered

*/

ssidFilter = TRUE;

/* Set the bss type scan filter, use Adapter setting if unset */ pScanCfgOut->bssType = (pUserScanIn->bssType ? pUserScanIn->bssType : Adapter->ScanMode);

/* Set the number of probes to send, use Adapter setting if unset */ numProbes = (pUserScanIn->numProbes ? pUserScanIn->numProbes :

Page: 8

F:\WiFi_V2.1\src\wifi\wlan_scan.c

Adapter->ScanProbes);

/*

* Set the BSSID filter to the incoming configuration,

* if non-zero. If not set, it will remain disabled (all zeros).

*/

memcpy(pScanCfgOut->specificBSSID,

pUserScanIn->specificBSSID,

sizeof(pScanCfgOut->specificBSSID));

for (ssidIdx = 0; ((ssidIdx ssidList))

&& (*pUserScanIn->ssidList[ssidIdx].ssid

|| pUserScanIn->ssidList[ssidIdx].maxLen));

ssidIdx++) {

ssidLen = strlen(pUserScanIn->ssidList[ssidIdx].ssid) + 1; pWildCardSsidTlv = (MrvlIEtypes_WildCardSsIdParamSet_t *) pTlvPos; pWildCardSsidTlv->Header.Type

= wlan_cpu_to_le16(TLV_TYPE_WILDCARDSSID);

pWildCardSsidTlv->Header.Len

= ssidLen + sizeof(pWildCardSsidTlv->MaxSsidLength);

pWildCardSsidTlv->MaxSsidLength

= pUserScanIn->ssidList[ssidIdx].maxLen;

memcpy(pWildCardSsidTlv->SsId,

pUserScanIn->ssidList[ssidIdx].ssid, ssidLen);

pTlvPos += (sizeof(pWildCardSsidTlv->Header)

+ pWildCardSsidTlv->Header.Len);

pWildCardSsidTlv->Header.Len

= wlan_cpu_to_le16(pWildCardSsidTlv->Header.Len);

printf( "Scan: ssidList[%d]: %s, %d\n",

ssidIdx,

pWildCardSsidTlv->SsId, pWildCardSsidTlv->MaxSsidLength);

/* Empty wildcard ssid with a maxlen will match many or potentially

* all SSIDs (maxlen == 32), therefore do not treat the scan

* as filtered.

*/

if ((ssidLen == 0) &&pWildCardSsidTlv->MaxSsidLength) {

ssidFilter = FALSE;

}

}

/*

* The default number of channels sent in the command is low to

* ensure the response buffer from the firmware does not truncate

* scan results. That is not an issue with an SSID or BSSID

* filter applied to the scan results in the firmware.

*/

if ((ssidIdx &&ssidFilter)

|| memcmp(pScanCfgOut->specificBSSID, &zeroMac, sizeof(zeroMac))) {

*pFilteredScan = TRUE;

}

} else {

pScanCfgOut->bssType = Adapter->ScanMode;

numProbes = Adapter->ScanProbes;

}

/* If the input config or adapter has the number of Probes set, add tlv */

if (numProbes) {

printf( "Scan: numProbes = %d\n", numProbes);

Page: 9

F:\WiFi_V2.1\src\wifi\wlan_scan.c

pNumProbesTlv = (MrvlIEtypes_NumProbes_t *) pTlvPos;

pNumProbesTlv->Header.Type = wlan_cpu_to_le16(TLV_TYPE_NUMPROBES); pNumProbesTlv->Header.Len = sizeof(pNumProbesTlv->NumProbes); pNumProbesTlv->NumProbes = wlan_cpu_to_le16(numProbes);

pTlvPos += sizeof(pNumProbesTlv->Header) + pNumProbesTlv->Header.Len; pNumProbesTlv->Header.Len =

wlan_cpu_to_le16(pNumProbesTlv->Header.Len);

}

wlan_add_wps_probe_request_ie(priv, &pTlvPos);

/*

* Set the output for the channel TLV to the address in the tlv buffer * past any TLVs that were added in this fuction (SSID, numProbes).

* Channel TLVs will be added past this for each scan command, preserving * the TLVs that were previously added.

*/

*ppChanTlvOut = (MrvlIEtypes_ChanListParamSet_t *) pTlvPos;

if (pUserScanIn &&pUserScanIn->chanList[0].chanNumber) {

printf( "Scan: Using supplied channel list\n");

for (chanIdx = 0;

chanIdx

&&pUserScanIn->chanList[chanIdx].chanNumber; chanIdx++) {

channel = pUserScanIn->chanList[chanIdx].chanNumber;

(pScanChanList + chanIdx)->ChanNumber = channel;

radioType = pUserScanIn->chanList[chanIdx].radioType;

(pScanChanList + chanIdx)->RadioType = radioType;

scanType = pUserScanIn->chanList[chanIdx].scanType;

if (scanType == HostCmd_SCAN_TYPE_PASSIVE) {

(pScanChanList + chanIdx)->ChanScanMode.PassiveScan = TRUE;

} else {

(pScanChanList + chanIdx)->ChanScanMode.PassiveScan = FALSE;

}

if (pUserScanIn->chanList[chanIdx].scanTime) {

scanDur = pUserScanIn->chanList[chanIdx].scanTime;

} else {

if (scanType == HostCmd_SCAN_TYPE_PASSIVE) {

scanDur = Adapter->PassiveScanTime;

} else if (*pFilteredScan) {

scanDur = Adapter->SpecificScanTime;

} else {

scanDur = Adapter->ActiveScanTime;

}

}

(pScanChanList + chanIdx)->MinScanTime =

wlan_cpu_to_le16(scanDur);

(pScanChanList + chanIdx)->MaxScanTime =

wlan_cpu_to_le16(scanDur);

}

/* Check if we are only scanning the current channel */

if ((chanIdx == 1)

&& (pUserScanIn->chanList[0].chanNumber

== priv->adapter->CurBssParams.BSSDescriptor.Channel)) {

*pScanCurrentOnly = TRUE;

printf( "Scan: Scanning current channel only");

}

Page: 10

F:\WiFi_V2.1\src\wifi\wlan_scan.c

} else {

printf( "Scan: Creating full region channel list\n");

wlan_scan_create_channel_list(priv, pScanChanList, *pFilteredScan);

}

}

/**

* @brief Construct and send multiple scan config commands to the firmware

* Previous routines have created a wlan_scan_cmd_config with any requested * TLVs. This function splits the channel TLV into maxChanPerScan lists * and sends the portion of the channel TLV along with the other TLVs * to the wlan_cmd routines for execution in the firmware.

*

* @param priv A pointer to wlan_private structure

* @param maxChanPerScan Maximum number channels to be included in each * scan command sent to firmware

* @param filteredScan Flag indicating whether or not a BSSID or SSID * filter is being used for the firmware command

* scan command sent to firmware

* @param pScanCfgOut Scan configuration used for this scan.

* @param pChanTlvOut Pointer in the pScanCfgOut where the channel TLV * should start. This is past any other TLVs that

* must be sent down in each firmware command.

* @param pScanChanList List of channels to scan in maxChanPerScan segments *

* @return WLAN_STATUS_SUCCESS or error return otherwise

*/

static int

wlan_scan_channel_list(wlan_private * priv,

int maxChanPerScan,

BOOLEAN filteredScan,

wlan_scan_cmd_config * pScanCfgOut,

MrvlIEtypes_ChanListParamSet_t * pChanTlvOut,

ChanScanParamSet_t * pScanChanList)

{

ChanScanParamSet_t *pTmpChan;

//ChanScanParamSet_t *pStartChan;

//u8 scanBand;

int doneEarly;

int tlvIdx;

int totalscantime;

int ret;

ENTER();

if (pScanCfgOut == 0 || pChanTlvOut == 0 || pScanChanList == 0) { printf( "Scan: Null detect: %p, %p, %p\n",

pScanCfgOut, pChanTlvOut, pScanChanList);

return WLAN_STATUS_FAILURE;

}

ret = WLAN_STATUS_SUCCESS;

pChanTlvOut->Header.Type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);

/* Set the temp channel struct pointer to the start of the desired list

pTmpChan = pScanChanList;

/* Loop through the desired channel list, sending a new firmware scan * commands for each maxChanPerScan channels (or for 1,6,11 individually * if configured accordingly)

*/

while (pTmpChan->ChanNumber) {

tlvIdx = 0;

totalscantime = 0;

Page: 11

F:\WiFi_V2.1\src\wifi\wlan_scan.c

pChanTlvOut->Header.Len = 0;

// scanBand = pTmpChan->RadioType;

// pStartChan = pTmpChan;

doneEarly = FALSE;

/* Construct the Channel TLV for the scan command. Continue to

* insert channel TLVs until:

* - the tlvIdx hits the maximum configured per scan command

* - the next channel to insert is 0 (end of desired channel list)

* - doneEarly is set (controlling individual scanning of 1,6,11)

*/

while (tlvIdx ChanNumber && !doneEarly) { printf( "Scan: Chan(%3d), Radio(%d), Mode(%d,%d), Dur(%d)\n", pTmpChan->ChanNumber,

pTmpChan->RadioType,

pTmpChan->ChanScanMode.PassiveScan,

pTmpChan->ChanScanMode.DisableChanFilt,

pTmpChan->MaxScanTime);

/* Copy the current channel TLV to the command being prepared */ memcpy(pChanTlvOut->ChanScanParam + tlvIdx,

pTmpChan, sizeof(pChanTlvOut->ChanScanParam));

/* Increment the TLV header length by the size appended */

pChanTlvOut->Header.Len += sizeof(pChanTlvOut->ChanScanParam);

/*

* The tlv buffer length is set to the number of bytes of the

* between the channel tlv pointer and the start of the

* tlv buffer. This compensates for any TLVs that were appended

* before the channel list.

*/

pScanCfgOut->tlvBufferLen = ((u8 *) pChanTlvOut

- pScanCfgOut->tlvBuffer);

/* Add the size of the channel tlv header and the data length */ pScanCfgOut->tlvBufferLen += (sizeof(pChanTlvOut->Header)

+ pChanTlvOut->Header.Len);

/* Increment the index to the channel tlv we are constructing */

tlvIdx++;

/* Count the total scan time per command */

totalscantime += pTmpChan->MaxScanTime;

doneEarly = FALSE;

/* Stop the loop if the *current* channel is in the 1,6,11 set

* and we are not filtering on a BSSID or SSID.

*/

if (!filteredScan && (pTmpChan->ChanNumber == 1

|| pTmpChan->ChanNumber == 6

|| pTmpChan->ChanNumber == 11)) {

doneEarly = TRUE;

}

/* Increment the tmp pointer to the next channel to be scanned */ pTmpChan++;

/* Stop the loop if the *next* channel is in the 1,6,11 set.

* This will cause it to be the only channel scanned on the next

* interation

*/

if (!filteredScan && (pTmpChan->ChanNumber == 1

|| pTmpChan->ChanNumber == 6

|| pTmpChan->ChanNumber == 11)) {

doneEarly = TRUE;

Page: 12

F:\WiFi_V2.1\src\wifi\wlan_scan.c

}

}

/* The total scan time should be less than scan command timeout value */ if (totalscantime >MRVDRV_MAX_TOTAL_SCAN_TIME) {

printf(

"Total scan time %d ms is over limit (%d ms), scan skipped\n", totalscantime, MRVDRV_MAX_TOTAL_SCAN_TIME);

ret = WLAN_STATUS_FAILURE;

break;

}

pChanTlvOut->Header.Len = wlan_cpu_to_le16(pChanTlvOut->Header.Len); /* Send the scan command to the firmware with the specified cfg */

ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_SCAN, 0,

HostCmd_OPTION_WAITFORRSP, 0,

pScanCfgOut);

}

LEAVE();

if (ret) {

return WLAN_STATUS_FAILURE;

}

return WLAN_STATUS_SUCCESS;

}

/**

* @brief Internal function used to start a scan based on an input config *

* Use the input user scan configuration information when provided in * order to send the appropriate scan commands to firmware to populate or * update the internal driver scan table

*

* @param priv A pointer to wlan_private structure

* @param pUserScanIn Pointer to the input configuration for the requested * scan.

*

* @return WLAN_STATUS_SUCCESS or < 0 if error

*/

static int

wlan_scan_networks(wlan_private * priv,

const wlan_ioctl_user_scan_cfg * pUserScanIn)

{

wlan_adapter *Adapter = priv->adapter;

MrvlIEtypes_ChanListParamSet_t *pChanTlvOut;

ChanScanParamSet_t scanChanList[WLAN_IOCTL_USER_SCAN_CHAN_MAX];

wlan_scan_cmd_config_tlv scanCfgOut;

BOOLEAN keepPreviousScan;

BOOLEAN filteredScan;

BOOLEAN scanCurrentChanOnly;

int maxChanPerScan;

int ret;

BOOLEAN bBgScan;

ENTER();

memset(scanChanList, 0x00, sizeof(scanChanList));

memset(&scanCfgOut, 0x00, sizeof(scanCfgOut));

keepPreviousScan = FALSE;

wlan_scan_setup_scan_config(priv,

pUserScanIn,

&scanCfgOut.config,

Page: 13

F:\WiFi_V2.1\src\wifi\wlan_scan.c

&pChanTlvOut,

scanChanList,

&maxChanPerScan,

&filteredScan, &scanCurrentChanOnly);

if (pUserScanIn) {

keepPreviousScan = pUserScanIn->keepPreviousScan;

}

if (keepPreviousScan == FALSE) {

memset(Adapter->ScanTable, 0x00,

sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST);

Adapter->NumInScanTable = 0;

Adapter->pBeaconBufEnd = Adapter->beaconBuffer;

}

/* Keep the data path active if we are only scanning our current channel */

if (!scanCurrentChanOnly) {

// printf( "Scan: WMM Queue stop\n");

// priv->wlan_https://www.doczj.com/doc/d1711795.html,dev->watchdog_timeo =

MRVDRV_SCAN_WATCHDOG_TIMEOUT;

/* If WMM queues are in use, only stop the internal data queues */ wmm_stop_queue(priv);

}

bBgScan = priv->adapter->bgScanConfig->Enable;

if (priv->adapter->bgScanConfig->Enable == TRUE) {

wlan_bg_scan_enable(priv, FALSE);

}

ret = wlan_scan_channel_list(priv,

maxChanPerScan,

filteredScan,

&scanCfgOut.config,

pChanTlvOut, scanChanList);

/* Process the resulting scan table:

* - Remove any bad ssids

* - Update our current BSS information from scan data

*/

wlan_scan_process_results(priv);

if (bBgScan == TRUE) {

wlan_bg_scan_enable(priv, TRUE);

}

printf( "Scan: WMM Queue start\n");

//priv->wlan_https://www.doczj.com/doc/d1711795.html,dev->watchdog_timeo =

MRVDRV_DEFAULT_WATCHDOG_TIMEOUT; xzw1234

if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {

wmm_start_queue(priv);

}

os_carrier_on(priv);

os_start_queue(priv);

LEAVE();

return ret;

}

/**

* @brief Create a brief scan resp to relay basic BSS info to the app layer *

* When the beacon/probe response has not been buffered, use the saved BSS * information available to provide a minimum response for the application * ioctl retrieval routines. Include:

* - Timestamp

* - Beacon Period

* - Capabilities (including WMM Element if available)

Page: 14

F:\WiFi_V2.1\src\wifi\wlan_scan.c

* - SSID

*

* @param ppBuffer Output parameter: Buffer used to create basic scan rsp * @param pBSSDesc Pointer to a BSS entry in the scan table to create * scan response from for delivery to the application layer

*

* @return void

*/

static void

wlan_scan_create_brief_table_entry(u8 ** ppBuffer, BSSDescriptor_t * pBSSDesc)

{

u8 *pTmpBuf = *ppBuffer;

u8 tmpSSIDHdr[2];

u8 ieLen;

if (copy_to_user(pTmpBuf, pBSSDesc->TimeStamp,

sizeof(pBSSDesc->TimeStamp))) {

PRINTM(INFO, "Copy to user failed\n");

return;

}

pTmpBuf += sizeof(pBSSDesc->TimeStamp);

if (copy_to_user(pTmpBuf, &pBSSDesc->BeaconPeriod,

sizeof(pBSSDesc->BeaconPeriod))) {

PRINTM(INFO, "Copy to user failed\n");

return;

}

pTmpBuf += sizeof(pBSSDesc->BeaconPeriod);

if (copy_to_user(pTmpBuf, &pBSSDesc->Cap, sizeof(pBSSDesc->Cap))) { PRINTM(INFO, "Copy to user failed\n");

return;

}

pTmpBuf += sizeof(pBSSDesc->Cap);

STM32F107+ULN2003+步进电机

STM32F107+ULN2003+步进电机,主要是步进电机部分,只写了正转,控制转速靠延时函数delayl(),反转的话还要写一个函数,将那把个数倒过来送过去,先送9,最后送8. int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ uint32_t Times = 0; uint8_t ucStr[80] = {0}; uint32_t num = 0; /* 3?ê??ˉ°???LED??ê?μ? */ SZ_STM32_LEDInit(LED1); SZ_STM32_LEDInit(LED2); SZ_STM32_LEDInit(LED3); SZ_STM32_LEDInit(LED4); SZ_STM32_SysTickInit(1000); SZ_STM32_COMInit(COM1, 115200); COTR_Init(); /* Infinite loop ?÷?-?· */ while (1) { /* LED1??ê?μ?×′ì?è?·′ */ LED1OBB = !LED1OBB; */ Zhengzhuan(); } } /*********μ??ú**********************/ void delayl(unsigned int dl) { unsigned int i,y; for(i = 0; i < 5000; i++)

基于STM32和L6208的步进电机控制系统

基于STM32和L6208的步进电机控制系统 摘要:本文介绍了步进电机的基本工作原理及控制方法,通过对ARM公司的STM32F103XX处理器Cortex-M3和ST公司步进电机驱动芯片L6208性能和驱动原理的深入分析,阐述了一种新型驱动步进电机的控制系统。本控制系统能够实时、准确、可靠地控制两相两极的步进电机。 关键词:STM32、L6208、步进电机 Abstract:This paper introduced the basic work principle and control methods, By introducing the performance of STM32F103XX and thorough analyzing the drive principle of DMOS driver for bipolar steeper motor L6208, I expounded a new control system for driving steeper motor. This control system can control bipolar stepper motor real-time, well and truly and reliably. Key words: STM32, L6208, stepper motor 第1章引言 本系统采用STM32F103XX微控制器驱动双极性步进电机的方法,执行整步和半步模式来控制步进电机。用户可以选择:操作模式(整步/半步);电机旋转方式(顺时针/逆时针);当前控制模式(快速/慢速)。这种方法使用中密度STM32F103XX微控制器和全集成两相步进电机驱动L6208,这是性价比最高和最简单的方式获得最小的CPU负载。Cortex-M3是专门在微控制系统和无线网络等对功耗和成本敏感的嵌入式应用领域实现高系统性能而设计的,它大大简化了编程的复杂性,集高性能、低功耗、低成本于一体。 本设计的主要特点: 1、不需反馈器件,比其他运动控制系统成本低。 2、尤其在低速扭转力和强稳定性方面具有优势。 3、低功耗,高性能并且灵活,可用于机器人控制,机械工具转弯处,影像和其它精准 的轴位置控制环境。 4、高性能的STM32F103XX微控制器驱动步进电机依赖于控制器的低计算环境。 第2章方案比较与论证 总体系统框图如图1所示:

基于STM32的步进电机控制系统

基于STM32的步进电机控制系统

摘要 本文的主要工作是基于STM32步进电机控制系统的设计。随着越来越多的高科技产品逐渐融入了日常生活中,步进电机控制系统发生了巨大的变化。单片机、C 语言等前沿学科的技术的日趋成熟与实用化,使得步进电机的控制系统有了新的的研究方向与意义。本文描述了一个由STM32微处理器、步进电机、LCD显示器、键盘等模块构成的,提供基于STM32的PWM细分技术的步进电机控制系统。该系统采用STM32微处理器为核心,在MDK的环境下进行编程,根据键盘的输入,使STM32产生周期性PWM信号,用此信号对步进电机的速度及转动方向进行控制,并且通过LCD显示出数据。结果表明该系统具有结构简单、工作可靠、精度高等特点. 关键词:STM32微处理器;步进电机;LCD显示;PWM信号;细分技术

Abstract As well as the high-tech products gradually integrated into the daily life,servo control system has undergone tremendous changes.SCM and C language of the frontier disciplines such mature technology and practical,steering control system is a new research direction and meaning.This paper describes a STM32 microprocessors, steering, LCD display and keyboard, Based on the STM32 servo control system of PWM signal,This system uses STM32 microprocessor as the core, MDK in the environment, according to the keyboard input , STM32 produce periodic PWM signal, with this signal to the velocity and Angle of steering gear control, and through the LCD display data. The features of the simple hardware, stable operation and high precision are incarnated in the proposed system. Keywords:STM32 microprocessors; Steering system; LCD display;pulse width modulation signal;Subdivide technology

7. STM32 控制步进电机正方转

实验目的:利用STM32 来控制步进电机正反转 实验设备:STM32开发板,两相步进电机,24V&5V直流电源,丝杆导轨,DM422C 驱动器 图1 实物图 第一步弄清楚驱动器接线 1.1 ENA可以悬空 大部分使用者就是将ENA悬空的,就是电机通常不锁轴 1.2 OPTO 是共阳极端 1.2.1 如果用的是AVR ,就直接接到AVR 5V接线柱上。 1.2.2 如果用的是ARM,就将OPTO接到5V 电源上,记得电源要和ARM共地,这样才能识别接的电源是5V 第二步弄清楚脉冲的发送形式,即Delay函数作用 清楚脉冲的发送形式,即Delay函数作用,

弄清楚接口由哪个GPIO口控制,然后连接硬件图, 通过电源IO控指示灯检验信号发送: 第三步主程序 下面这个程序是 /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" void Delay (u32 nCount) { for(; nCount != 0; nCount--); } void GPIO_Config() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE , ENABLE);

基于STM32的步进电机控制系统

基于STM32的步进电机控制系统 沈阳航空航天大学 2010年6月

摘要 本文的主要工作是基于STM32步进电机控制系统的设计。随着越来越多的高科技产品逐渐融入了日常生活中,步进电机控制系统发生了巨大的变化。单片机、C 语言等前沿学科的技术的日趋成熟与实用化,使得步进电机的控制系统有了新的的研究方向与意义。本文描述了一个由STM32微处理器、步进电机、LCD显示器、键盘等模块构成的,提供基于STM32的PWM细分技术的步进电机控制系统。该系统采用STM32微处理器为核心,在MDK的环境下进行编程,根据键盘的输入,使STM32产生周期性PWM信号,用此信号对步进电机的速度及转动方向进行控制,并且通过LCD显示出数据。结果表明该系统具有结构简单、工作可靠、精度高等特点. 关键词:STM32微处理器;步进电机;LCD显示;PWM信号;细分技术

Abstract As well as the high-tech products gradually integrated into the daily life,servo control system has undergone tremendous changes.SCM and C language of the frontier disciplines such mature technology and practical,steering control system is a new research direction and meaning.This paper describes a STM32 microprocessors, steering, LCD display and keyboard, Based on the STM32 servo control system of PWM signal,This system uses STM32 microprocessor as the core, MDK in the environment, according to the keyboard input , STM32 produce periodic PWM signal, with this signal to the velocity and Angle of steering gear control, and through the LCD display data. The features of the simple hardware, stable operation and high precision are incarnated in the proposed system. Keywords:STM32 microprocessors; Steering system; LCD display;pulse width modulation signal;Subdivide technology

STM32控制步进电机程序

#include "sys.h" #include "usart.h" #include "delay.h" #include "led.h" #include "timer.h" #include "key.h" int main(void) { u8 t; u32 v=100; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口初始化 LED_Init(); //初始化与LED连接的硬件接口KEY_Init(); //初始化与按键连接的硬件接口 RCC->APB2ENR|=1<<2; //使能PORTA时钟 GPIOA->CRL&=0X0FFFFFFF; GPIOA->CRL|=0X30000000;//PA7推挽输出 GPIOA->ODR|=1<<7; //PA7 输出高 GPIOA->CRL&=0XFF0FFFFF; GPIOA->CRL|=0X00300000;//PA5推挽输出 GPIOA->ODR|=1<<5; //PA5 输出高 LED1=1; LED0=1; while(1) { t=KEY_Scan(0); //得到键值 switch(t) { case KEY0_PRES: v=v+10; TIM3_Int_Init(v,7199);//10Khz的计数频率 TIM3->CR1|=0x01; break; case KEY1_PRES: v=v-10 ; TIM3_Int_Init(v,7199);//10Khz的计数频率 TIM3->CR1|=0x01; //使能定时器3 break; case WKUP_PRES: TIM3->CR1&=0xFE;//关定时器3; break; }

STM32用IO口控制步进电机的简单程序

STM32用IO口控制步进电机的简单程序 练习IO口库函数操作。//相序uint16_tphasecw[4] ={0x2000,0x0001,0x0004,0x0008};//D-C-B- Auint16_tphaseccw[4]={0x0008,0x0004,0x0001,0x2000};//A-B-C-D //步进电机相关IO口初始化 //IN4:PC13//IN3:PC0//IN2:PC2//IN1:PC3voidMoto_Init(void){GPIO_InitTypeDefG PIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABL E);//GPIOCLOCKENABLEGPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;GPIO_Ini tStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//50MHz速率 GPIO_Init(GPIOC,&GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_13);// 输出低电平 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_Init(GPIOC,&GPIO_InitStructur e);GPIO_ResetBits(GPIOC,GPIO_Pin_0);GPIO_InitStructure.GPIO_Pin=GPIO_Pin _2;GPIO_Init(GPIOC,&GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;GPIO_Init(GPIOC,&GPIO_InitStructur e);GPIO_ResetBits(GPIOC,GPIO_Pin_3);} //电机正转voidMotorcw(void){uint8_ti;for(i=0;i记得使能IO口时钟。 tips:感谢大家的阅读,本文由我司收集整编。仅供参阅!

步进电机-插补算法stm32

#include "stm32f10x.h" #include "delay.h" #include "misc.h" #include #include "stm32f10x_tim.h" #include "stm32f10x_rcc.h" #include "stm32f10x_usart.h" #include voidRCC_Configuration(void); voidGPIO_Configuration(void); voidNVIC_Configuration(void); voidTIM_Configuration(void); voidUSART_Configuration(void); intfputc(intch,FILE *f); intfgetc(FILE *f); float Mx=1.44f,My=2.88f;//起点 float Nx=10.0f,Ny=7.61f;//终点 float X1,Y1; float X2,Y2; float X3,Y3;//三种方法走后的坐标 float k;//斜率 float b;//y=kx+b float X,Y;//实际运行的坐标 float Delta1,Delta2,Delta3,Delta4;//三种方法的误差,4为不走最后一步的误差float Delta;//实际误差 // float DeltaMax;//最大误差 char way;//选择的走法 int a;//TIM6 中断次数 intnum=0;//总步数 inttx=1,ty=1;//用来判断中断是否发生 intnumx,numy;//计XY的步数 int counter=0;//计数值 float time;//时间 float nxd,nyd;//开始减速坐标 floatnx,ny;//nx=Nx-0.0144f; float fenmu;//公式中分母 // intfrex[20]={2,10,30,60,100,150,220,300,390,500}; // intfrey[20]={2,10,30,60,100,150,220,300,390,500}; int frex[20]={1098,2931,7585,18242,37754,62245,81757,92414,97068,98901}; int frey[20]={1098,2931,7585,18242,37754,62245,81757,92414,97068,98901}; intprex[20]={0};

基于stm32的步进电机控制系统嵌入式课程设计

课程设计报告书 题目: 基于stm32的步进电机控制系统 课程:嵌入式系统课程设计 专业:电子信息科学与技术 2016年 4 月 15 日

课程设计任务书

信息工程学院课程设计成绩评定表

摘要 本文的主要工作是基于STM32步进电机控制系统的设计。随着越来越多的高科技产品逐渐融入了日常生活中,步进电机控制系统发生了巨大的变化。单片机、C语言等前沿学科的技术的日趋成熟与实用化,使得步进电机的控制系统有了新的的研究方向与意义。本文描述了一个由STM32微处理器、步进电机、LCD显示器、键盘等模块构成的,提供基于STM32的PWM细分技术的步进电机控制系统。该系统采用STM32微处理器为核心,在MDK的环境下进行编程,根据键盘的输入,使STM32产生周期性PWM信号,用此信号对步进电机的速度及转动方向进行控制,并且通过LCD显示出数据。结果表明该系统具有结构简单、工作可靠、精度高等特点. 关键词:STM32微处理器;步进电机;LCD显示;PWM信号; 目录 1 任务提出与方案论证 (5) 1.1 任务提出 (5) 1.2 方案论证 (5) 2 总体设计 (6) 2.1系统的硬件设计 (6) 2.2控制系统软件设计 (6) 3 详细设计及仿真 (8) 3.1设计主要程序部分 (8) 3.2调试与仿真 (9) 4 总结 (10) 5 实物图和仿真图 (11)

1 任务提出与方案论证 步进电机控制系统的整个设计中最重要的部分是利用PWM细分实现步进电机调速的处理,虽然PWM调速很早就开始研究应用,但如何用PWM细分调速的快速性和准确性至今仍是生产和科研的课题。随着微电子技术的发展与普及,更多高性能的单片机应用使得PWM细分实现步进电机PWM调速的快速性和准确性都有了极大的提高。 1.1 任务提出 总体方案根据课题要求,本设计采用STM32cortex-M3处理器,由SPGT62C19B 电机控制模块作为直流电机的驱动芯片,由ADC输入电位器产生调速命令,用TFT彩色LCD作为显示模块。 1.2 方案论证 步进电机控制系统硬件方案 本系统主要由一块STM32平台、SPGT62C19B型步进电机驱动模块构成,以STM32为核心,包括电机驱动、电机、A/D转换、LCD显示等模块。系统的结构框图如图 2.1所示。 STM32作为主控芯片,通过I/O端口来控制SPGT62C19B型步进电机驱动芯片,从而实现对步进电机的控制。通过ADC输入电位器产生调速命令反馈给STM32,STM32调节SPGT62C19B型步进电机驱动模块的状态,从而使电机改变转速和方向。同时,电机转速可由彩色液晶LCD显示出来,用ADC输入电位器来对步进电机的转动方向和转速等进行设定。 步进电机控制系统软件方案 硬件功能的实现离不开软件的设计与完成。软件设计是步进电机控制系统设计中最重要、最关键的部分,也是本次毕业设计的难点之处。由于本系统使用STM32平台,运用Keil for ARM开发环境,在Keil u Vision软件平台进行开发。本课题软件设计的思想主要是自顶向下,模块化设计,逐一设计各个子模块,分别进行调试,最后的连调整个程序,判断是否达到预期的要求,做出结论。各个部分函数都可相互调用又相对独立可调,保证调试的便利与程序的可读性。

相关主题
文本预览
相关文档 最新文档